From 00d8521dcd236d1b8f664f54a0309e96bfdcb4f9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 23 May 2014 20:46:41 +0900 Subject: [PATCH] staging: remove rts5139 driver code Roger writes: Since all patches have been applied and the device is now supported by the new driver, would you remove the former staging one at drivers/staging/rts5139? Cc: Roger Tseng Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/rts5139/Kconfig | 16 - drivers/staging/rts5139/Makefile | 43 - drivers/staging/rts5139/TODO | 9 - drivers/staging/rts5139/debug.h | 46 - drivers/staging/rts5139/ms.c | 4182 -------------------- drivers/staging/rts5139/ms.h | 261 -- drivers/staging/rts5139/ms_mg.c | 643 --- drivers/staging/rts5139/ms_mg.h | 42 - drivers/staging/rts5139/rts51x.c | 846 ---- drivers/staging/rts5139/rts51x.h | 194 - drivers/staging/rts5139/rts51x_card.c | 940 ----- drivers/staging/rts5139/rts51x_card.h | 870 ---- drivers/staging/rts5139/rts51x_chip.c | 1014 ----- drivers/staging/rts5139/rts51x_chip.h | 821 ---- drivers/staging/rts5139/rts51x_fop.c | 295 -- drivers/staging/rts5139/rts51x_fop.h | 57 - drivers/staging/rts5139/rts51x_scsi.c | 2135 ---------- drivers/staging/rts5139/rts51x_scsi.h | 154 - drivers/staging/rts5139/rts51x_transport.c | 738 ---- drivers/staging/rts5139/rts51x_transport.h | 67 - drivers/staging/rts5139/sd.c | 3274 --------------- drivers/staging/rts5139/sd.h | 275 -- drivers/staging/rts5139/sd_cprm.c | 1056 ----- drivers/staging/rts5139/sd_cprm.h | 54 - drivers/staging/rts5139/trace.h | 95 - drivers/staging/rts5139/xd.c | 2145 ---------- drivers/staging/rts5139/xd.h | 191 - 29 files changed, 20466 deletions(-) delete mode 100644 drivers/staging/rts5139/Kconfig delete mode 100644 drivers/staging/rts5139/Makefile delete mode 100644 drivers/staging/rts5139/TODO delete mode 100644 drivers/staging/rts5139/debug.h delete mode 100644 drivers/staging/rts5139/ms.c delete mode 100644 drivers/staging/rts5139/ms.h delete mode 100644 drivers/staging/rts5139/ms_mg.c delete mode 100644 drivers/staging/rts5139/ms_mg.h delete mode 100644 drivers/staging/rts5139/rts51x.c delete mode 100644 drivers/staging/rts5139/rts51x.h delete mode 100644 drivers/staging/rts5139/rts51x_card.c delete mode 100644 drivers/staging/rts5139/rts51x_card.h delete mode 100644 drivers/staging/rts5139/rts51x_chip.c delete mode 100644 drivers/staging/rts5139/rts51x_chip.h delete mode 100644 drivers/staging/rts5139/rts51x_fop.c delete mode 100644 drivers/staging/rts5139/rts51x_fop.h delete mode 100644 drivers/staging/rts5139/rts51x_scsi.c delete mode 100644 drivers/staging/rts5139/rts51x_scsi.h delete mode 100644 drivers/staging/rts5139/rts51x_transport.c delete mode 100644 drivers/staging/rts5139/rts51x_transport.h delete mode 100644 drivers/staging/rts5139/sd.c delete mode 100644 drivers/staging/rts5139/sd.h delete mode 100644 drivers/staging/rts5139/sd_cprm.c delete mode 100644 drivers/staging/rts5139/sd_cprm.h delete mode 100644 drivers/staging/rts5139/trace.h delete mode 100644 drivers/staging/rts5139/xd.c delete mode 100644 drivers/staging/rts5139/xd.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index f0cf26959fae..4f38fc000a37 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -54,8 +54,6 @@ source "drivers/staging/rtl8723au/Kconfig" source "drivers/staging/rtl8821ae/Kconfig" -source "drivers/staging/rts5139/Kconfig" - source "drivers/staging/rts5208/Kconfig" source "drivers/staging/frontier/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f60f26f537df..1e97ad2177de 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_R8188EU) += rtl8188eu/ obj-$(CONFIG_R8192EE) += rtl8192ee/ obj-$(CONFIG_R8723AU) += rtl8723au/ obj-$(CONFIG_R8821AE) += rtl8821ae/ -obj-$(CONFIG_RTS5139) += rts5139/ obj-$(CONFIG_RTS5208) += rts5208/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_IDE_PHISON) += phison/ diff --git a/drivers/staging/rts5139/Kconfig b/drivers/staging/rts5139/Kconfig deleted file mode 100644 index afd526bf422a..000000000000 --- a/drivers/staging/rts5139/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -config RTS5139 - tristate "Realtek RTS5139 USB card reader support" - depends on USB && SCSI - help - Say Y here to include driver code to support the Realtek - RTS5139 USB card readers. - - If this driver is compiled as a module, it will be named rts5139. - -config RTS5139_DEBUG - bool "Realtek RTS5139 Card Reader verbose debug" - depends on RTS5139 - help - Say Y here in order to have the rts5139 code generate - verbose debugging messages. - diff --git a/drivers/staging/rts5139/Makefile b/drivers/staging/rts5139/Makefile deleted file mode 100644 index 75dd31224e62..000000000000 --- a/drivers/staging/rts5139/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Driver for Realtek RTS51xx USB card reader -# -# Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, see . -# -# Author: -# wwang (wei_wang@realsil.com.cn) -# No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China -# Maintainer: -# Edwin Rong (edwin_rong@realsil.com.cn) -# No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China -# -# Makefile for the RTS51xx USB Card Reader drivers. -# - -obj-$(CONFIG_RTS5139) := rts5139.o - -ccflags-y := -Idrivers/scsi - -rts5139-y := \ - rts51x_transport.o \ - rts51x_scsi.o \ - rts51x_fop.o \ - rts51x.o \ - rts51x_chip.o \ - rts51x_card.o \ - xd.o \ - sd.o \ - ms.o \ - sd_cprm.o \ - ms_mg.o diff --git a/drivers/staging/rts5139/TODO b/drivers/staging/rts5139/TODO deleted file mode 100644 index dd5fabb8ea70..000000000000 --- a/drivers/staging/rts5139/TODO +++ /dev/null @@ -1,9 +0,0 @@ -TODO: -- support more USB card reader of Realtek family -- use kernel coding style -- checkpatch.pl fixes -- stop having thousands of lines of code duplicated with staging/rts_pstor -- This driver contains an entire SD/MMC stack -- it should use the stack in - drivers/mmc instead, as a host driver e.g. drivers/mmc/host/realtek-usb.c; - see drivers/mmc/host/ushc.c as an example. -- This driver presents cards as SCSI devices, but they should be MMC devices. diff --git a/drivers/staging/rts5139/debug.h b/drivers/staging/rts5139/debug.h deleted file mode 100644 index 73dec133a1bf..000000000000 --- a/drivers/staging/rts5139/debug.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_DEBUG_H -#define __RTS51X_DEBUG_H - -#include - -#define RTS51X_TIP "rts51x: " - -#ifdef CONFIG_RTS5139_DEBUG -#define RTS51X_DEBUGP(x...) printk(KERN_DEBUG RTS51X_TIP x) -#define RTS51X_DEBUGPN(x...) printk(KERN_DEBUG x) -#define RTS51X_DEBUGPX(x...) printk(x) -#define RTS51X_DEBUG(x) x -#else -#define RTS51X_DEBUGP(x...) -#define RTS51X_DEBUGPN(x...) -#define RTS51X_DEBUGPX(x...) -#define RTS51X_DEBUG(x) -#endif - -#endif /* __RTS51X_DEBUG_H */ diff --git a/drivers/staging/rts5139/ms.c b/drivers/staging/rts5139/ms.c deleted file mode 100644 index a843a2f4392b..000000000000 --- a/drivers/staging/rts5139/ms.c +++ /dev/null @@ -1,4182 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include -#include - -#include "debug.h" -#include "trace.h" -#include "rts51x.h" -#include "rts51x_transport.h" -#include "rts51x_scsi.h" -#include "rts51x_card.h" -#include "ms.h" -#include "ms_mg.h" - -static inline void ms_set_err_code(struct rts51x_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 rts51x_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 rts51x_chip *chip) -{ - TRACE_RET(chip, STATUS_FAIL); -} - -static int ms_transfer_tpc(struct rts51x_chip *chip, u8 trans_mode, u8 tpc, - u8 cnt, u8 cfg) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - RTS51X_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | trans_mode); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - rts51x_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 2, 5000); - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - rts51x_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - if (!(tpc & 0x08)) { /* Read Packet */ - /* Check CRC16 & Ready Timeout */ - if (chip->rsp_buf[1] & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } else { /* Write Packet */ - if (CHK_MSPRO(ms_card) && !(chip->rsp_buf[1] & 0x80)) { - if (chip->rsp_buf[1] & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } - } - - /* Check Timeout of Ready Signal */ - if (chip->rsp_buf[1] & MS_RDY_TIMEOUT) { - rts51x_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - return STATUS_SUCCESS; -} - -int ms_transfer_data(struct rts51x_chip *chip, u8 trans_mode, u8 tpc, - u16 sec_cnt, u8 cfg, int mode_2k, int use_sg, void *buf, - int buf_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 val, err_code = 0, flag = 0; - enum dma_data_direction dir; - unsigned int pipe; - - if (!buf || !buf_len) - TRACE_RET(chip, STATUS_FAIL); - - if (trans_mode == MS_TM_AUTO_READ) { - pipe = RCV_BULK_PIPE(chip); - dir = DMA_FROM_DEVICE; - flag = MODE_CDIR; - err_code = MS_FLASH_READ_ERROR; - } else if (trans_mode == MS_TM_AUTO_WRITE) { - pipe = SND_BULK_PIPE(chip); - dir = DMA_TO_DEVICE; - flag = MODE_CDOR; - err_code = MS_FLASH_WRITE_ERROR; - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, - (u8) (sec_cnt >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, - (u8) sec_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - RING_BUFFER); - - if (mode_2k) - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, - MS_2K_SECTOR_MODE); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, - 0); - - rts51x_trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | trans_mode); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, flag | STAGE_MS_STATUS, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - rts51x_transfer_data_rcc(chip, pipe, buf, buf_len, use_sg, NULL, - 15000, flag); - if (retval != STATUS_SUCCESS) { - ms_set_err_code(chip, err_code); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, retval); - } - - retval = rts51x_get_rsp(chip, 3, 15000); - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - ms_set_err_code(chip, err_code); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - ms_card->last_rw_int = val = chip->rsp_buf[1]; - if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int ms_write_bytes(struct rts51x_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)) - TRACE_RET(chip, STATUS_ERROR); - - rts51x_init_cmd(chip); - - for (i = 0; i < cnt; i++) { - rts51x_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, - data[i]); - } - if (cnt % 2) - rts51x_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, - 0xFF, 0xFF); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_WRITE_BYTES); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 1, 5000); - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - u8 val = 0; - - rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); - RTS51X_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val); - - rts51x_clear_ms_error(chip); - - if (!(tpc & 0x08)) { /* Read Packet */ - /* Check CRC16 & Ready Timeout */ - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } else { /* Write Packet */ - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, - ms_parse_err_code(chip)); - } - } - } - - /* Check Timeout of Ready Signal */ - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - return STATUS_SUCCESS; -} - -int ms_read_bytes(struct rts51x_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) - TRACE_RET(chip, STATUS_ERROR); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_READ_BYTES); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - for (i = 0; i < data_len - 1; i++) - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); - - if (data_len % 2) - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, - 0); - else - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, - 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, data_len + 1, 5000); - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - u8 val = 0; - - rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); - RTS51X_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val); - - rts51x_clear_ms_error(chip); - - if (!(tpc & 0x08)) { /* Read Packet */ - /* Check CRC16 & Ready Timeout */ - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } else { /* Write Packet */ - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, - ms_parse_err_code(chip)); - } - } - } - - /* Check Timeout of Ready Signal */ - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - rts51x_read_rsp_buf(chip, 1, data, data_len); - - return STATUS_SUCCESS; -} - -int ms_set_rw_reg_addr(struct rts51x_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; - rts51x_clear_ms_error(chip); - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int ms_send_cmd(struct rts51x_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_cmd(struct rts51x_chip *chip, - u8 read_start, u8 read_count, - u8 write_start, u8 write_count, - u8 cmd, u8 cfg, u8 *data, int data_len, u8 *int_stat) -{ - int retval, i; - u8 val; - - if (!data || (data_len <= 0) || (data_len > 128)) { - RTS51X_DEBUGP("ms_set_cmd (data_len = %d)\n", data_len); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = - ms_set_rw_reg_addr(chip, read_start, read_count, write_start, - write_count); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = - ms_write_bytes(chip, WRITE_REG, write_count, NO_WAIT_INT, - data, data_len); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, cmd, WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - /* GET_INT Register */ - 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) - TRACE_RET(chip, retval); - - if (int_stat) - *int_stat = val; - - return STATUS_SUCCESS; -} - -#ifdef MS_SPEEDUP -static int ms_auto_set_cmd(struct rts51x_chip *chip, - u8 read_start, u8 read_count, - u8 write_start, u8 write_count, - u8 cmd, u8 cfg, u8 *data, int data_len, - u8 *int_stat) -{ - int retval; - int i; - - if (!data || (data_len <= 0) || (data_len > 128)) { - RTS51X_DEBUGP("ms_auto_set_cmd (data_len = %d)\n", data_len); - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_READ_START, 0xFF, read_start); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_READ_COUNT, 0xFF, read_count); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_WRITE_START, 0xFF, write_start); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_WRITE_COUNT, 0xFF, write_count); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_COMMAND, 0xFF, cmd); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - for (i = 0; i < data_len; i++) { - rts51x_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, - data[i]); - } - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_SET_CMD); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR | STAGE_MS_STATUS, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 3, 5000); - - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - rts51x_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - if (int_stat) - *int_stat = chip->rsp_buf[2]; - - return STATUS_SUCCESS; -} -#endif - -static int ms_set_init_para(struct rts51x_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->option.asic_ms_hg_clk; - else - ms_card->ms_clock = chip->option.fpga_ms_hg_clk; - } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { - if (chip->asic_code) - ms_card->ms_clock = chip->option.asic_ms_4bit_clk; - else - ms_card->ms_clock = chip->option.fpga_ms_4bit_clk; - } else { - if (chip->asic_code) - ms_card->ms_clock = 38; - else - ms_card->ms_clock = CLK_40; - } - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int ms_switch_clock(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - retval = rts51x_select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static void ms_pull_ctl_disable(struct rts51x_chip *chip) -{ - if (CHECK_PKG(chip, LQFP48)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); - } -} - -static void ms_pull_ctl_enable(struct rts51x_chip *chip) -{ - if (CHECK_PKG(chip, LQFP48)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); - } -} - -static int ms_prepare_reset(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - 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; - - rts51x_init_cmd(chip); - - if (chip->asic_code) { - ms_pull_ctl_enable(chip); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, - FPGA_MS_PULL_CTL_BIT | 0x20, 0); - } - /* Tri-state MS output */ - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); - - if (!chip->option.FT2_fast_mode) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - } - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (!chip->option.FT2_fast_mode) { - wait_timeout(250); - - rts51x_card_power_on(chip, MS_CARD); - wait_timeout(150); - -#ifdef SUPPORT_OCP - rts51x_get_card_status(chip, &(chip->card_status)); - /* get OCP status */ - chip->ocp_stat = (chip->card_status >> 4) & 0x03; - - if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { - RTS51X_DEBUGP("Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - - rts51x_init_cmd(chip); - - /* Enable MS Output */ - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, - MS_OUTPUT_EN); - - /* Reset Registers */ - if (chip->asic_code) - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, 0xFF, - SAMPLE_TIME_RISING | PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, 0xFF, - SAMPLE_TIME_FALLING | PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, - NO_WAIT_INT | NO_AUTO_READ_INT_REG); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return ms_set_init_para(chip); -} - -static int ms_identify_media_type(struct rts51x_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_StatusReg, 6, SystemParm, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - /* Get Register form MS-PRO card */ - 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) - TRACE_RET(chip, STATUS_FAIL); - - RTS51X_READ_REG(chip, PPBUF_BASE2 + 2, &val); - RTS51X_DEBUGP("Type register: 0x%x\n", val); - if (val != 0x01) { - if (val != 0x02) - ms_card->check_ms_flow = 1; - TRACE_RET(chip, STATUS_FAIL); - } - /* Category Register */ - RTS51X_READ_REG(chip, PPBUF_BASE2 + 4, &val); - RTS51X_DEBUGP("Category register: 0x%x\n", val); - if (val != 0) { - ms_card->check_ms_flow = 1; - TRACE_RET(chip, STATUS_FAIL); - } - /* Class Register */ - RTS51X_READ_REG(chip, PPBUF_BASE2 + 5, &val); - RTS51X_DEBUGP("Class register: 0x%x\n", val); - if (val == 0) { - RTS51X_READ_REG(chip, PPBUF_BASE2, &val); - 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; - TRACE_RET(chip, STATUS_FAIL); - } - - ms_card->ms_type |= TYPE_MSPRO; - - /* Check MSPro-HG Card, use IF Mode Register to distinguish */ - RTS51X_READ_REG(chip, PPBUF_BASE2 + 3, &val); - RTS51X_DEBUGP("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 { - TRACE_RET(chip, STATUS_FAIL); - } - - /* end Procedure to identify Media Type */ - return STATUS_SUCCESS; -} - -static int ms_confirm_cpu_startup(struct rts51x_chip *chip) -{ - int retval, i, k; - u8 val; - - /* Confirm CPU StartUp */ - k = 0; - do { - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, 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) - TRACE_RET(chip, STATUS_FAIL); - - if (k > 100) - TRACE_RET(chip, 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) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_ERR) { - if (val & INT_REG_CMDNK) { /* CMDNK = 1 */ - chip->card_wp |= (MS_CARD); - } else { /* CMDNK = 0 */ - TRACE_RET(chip, STATUS_FAIL); - } - } - /*-- end confirm CPU startup */ - - return STATUS_SUCCESS; -} - -static int ms_switch_parallel_bus(struct rts51x_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) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int ms_switch_8bit_bus(struct rts51x_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) - TRACE_RET(chip, STATUS_FAIL); - - RTS51X_WRITE_REG(chip, MS_CFG, 0x98, - MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); - ms_card->ms_type |= MS_8BIT; - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int ms_pro_reset_flow(struct rts51x_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) - TRACE_RET(chip, retval); - - retval = ms_identify_media_type(chip, switch_8bit_bus); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = ms_confirm_cpu_startup(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = ms_switch_parallel_bus(chip); - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, STATUS_FAIL); - continue; - } else { - break; - } - } - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); - - RTS51X_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD); - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (CHK_MSHG(ms_card) && switch_8bit_bus) { - retval = ms_switch_8bit_bus(chip); - if (retval != STATUS_SUCCESS) { - ms_card->switch_8bit_fail = 1; - TRACE_RET(chip, retval); - } - } - - return STATUS_SUCCESS; -} - -#ifdef XC_POWERCLASS -static int msxc_change_power(struct rts51x_chip *chip, u8 mode) -{ - int retval; - u8 buf[6]; - - rts51x_ms_cleanup_work(chip); - - /* Set Parameter Register */ - retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - - retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_READ_REG(chip, MS_TRANS_CFG, buf); - if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} -#endif - -static int ms_read_attribute_info(struct rts51x_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_IntReg, 2, Pro_SystemParm, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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; - /* Start address 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) - TRACE_RET(chip, retval); - - buf = kmalloc(64 * 512, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, STATUS_NOMEM); - - 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 = rts51x_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if (!(val & MS_INT_BREQ)) { - kfree(buf); - TRACE_RET(chip, 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; - else - rts51x_clear_ms_error(chip); - } - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, retval); - } - - i = 0; - do { - retval = rts51x_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, retval); - } - - 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); - TRACE_RET(chip, retval); - } - - i++; - } while (i < 1024); - - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, retval); - } - - if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) { - /* Signature code is wrong */ - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - if ((buf[4] < 1) || (buf[4] > 12)) { - kfree(buf); - TRACE_RET(chip, 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]; - RTS51X_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n", - sys_info_addr, sys_info_size); - if (sys_info_size != 96) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if (sys_info_addr < 0x1A0) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if ((sys_info_size + sys_info_addr) > 0x8000) { - kfree(buf); - TRACE_RET(chip, 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]; - RTS51X_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n", - model_name_addr, model_name_size); - if (model_name_size != 48) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if (model_name_addr < 0x1A0) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if ((model_name_size + model_name_addr) > 0x8000) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - found_model_name = 1; - } - - if (found_sys_info && found_model_name) - break; -#endif - } - - if (i == buf[4]) { - kfree(buf); - TRACE_RET(chip, 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]; - RTS51X_DEBUGP("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]; - RTS51X_DEBUGP("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]; - RTS51X_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, - blk_size); -#endif - - RTS51X_DEBUGP("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); - - /* Confirm System Information */ -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - if (class_code != 0x03) - TRACE_RET(chip, STATUS_FAIL); - } else { - if (class_code != 0x02) - TRACE_RET(chip, STATUS_FAIL); - } -#else - if (class_code != 0x02) - TRACE_RET(chip, STATUS_FAIL); -#endif - - if (device_type != 0x00) { - if ((device_type == 0x01) || (device_type == 0x02) - || (device_type == 0x03)) - chip->card_wp |= MS_CARD; - else - TRACE_RET(chip, STATUS_FAIL); - } - if (sub_class & 0xC0) - TRACE_RET(chip, STATUS_FAIL); - - RTS51X_DEBUGP("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 - chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity = - total_blk * blk_size; -#endif - - return STATUS_SUCCESS; -} - -static int reset_ms_pro(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; -#ifdef XC_POWERCLASS - u8 change_power_class = 2; -#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) - TRACE_RET(chip, retval); - } else { - TRACE_RET(chip, retval); - } - } - - retval = ms_read_attribute_info(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#ifdef XC_POWERCLASS - if (CHK_HG8BIT(ms_card)) - change_power_class = 0; - - if (change_power_class && CHK_MSXC(ms_card)) { - u8 power_class_mode = (ms_card->raw_sys_info[46] & 0x18) >> 3; - RTS51X_DEBUGP("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 = rts51x_mg_set_tpc_para_sub(chip, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#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 rts51x_chip *chip) -{ - int retval; - u8 val[2]; - - retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int ms_check_boot_block(struct rts51x_chip *chip, u16 block_addr) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 extra[MS_EXTRA_SIZE], data[10], val = 0; - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (block_addr >> 8); - data[3] = (u8) block_addr; - /* Page Number - * Extra data access mode */ - data[4] = 0x40; - data[5] = 0; - - retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, - BLOCK_READ, WAIT_INT, data, 6, &val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, - MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - } - - retval = - ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, extra, - MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (!(extra[0] & BLOCK_OK) || (extra[1] & NOT_BOOT_BLOCK)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_read_extra_data(struct rts51x_chip *chip, - u16 block_addr, u8 page_num, u8 *buf, - int buf_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 val = 0, data[10]; - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (block_addr >> 8); - data[3] = (u8) block_addr; - /* Page Number - * Extra data access mode */ - data[4] = 0x40; - data[5] = page_num; - -#ifdef MS_SPEEDUP - retval = - ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, - BLOCK_READ, WAIT_INT, data, 6, &val); -#else - retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, - BLOCK_READ, WAIT_INT, data, 6, &val); -#endif - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, - MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - } - - retval = - ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, data, - MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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 rts51x_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 = 0, data[16]; - - if (!buf || (buf_len < MS_EXTRA_SIZE)) - TRACE_RET(chip, STATUS_FAIL); - /* Write REG */ - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (block_addr >> 8); - data[3] = (u8) block_addr; - /* Page Number - * Extra data access mode */ - data[4] = 0x40; - data[5] = page_num; - - for (i = 6; i < MS_EXTRA_SIZE + 6; i++) - data[i] = buf[i - 6]; - -#ifdef MS_SPEEDUP - retval = - ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, - 6 + MS_EXTRA_SIZE, BLOCK_WRITE, WAIT_INT, data, 16, - &val); -#else - retval = - ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, - 6 + MS_EXTRA_SIZE, BLOCK_WRITE, WAIT_INT, data, 16, - &val); -#endif - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - return STATUS_SUCCESS; -} - -static int ms_read_page(struct rts51x_chip *chip, u16 block_addr, u8 page_num) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 val = 0, data[6]; - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (block_addr >> 8); - data[3] = (u8) block_addr; - /* Page Number - * Single page access mode */ - data[4] = 0x20; - data[5] = page_num; - - retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, - BLOCK_READ, WAIT_INT, data, 6, &val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, 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); - TRACE_RET(chip, 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); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - retval = - ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, - NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_set_bad_block(struct rts51x_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 val = 0, data[8], extra[MS_EXTRA_SIZE]; - - retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - 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; - -#ifdef MS_SPEEDUP - retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7, - BLOCK_WRITE, WAIT_INT, data, 7, &val); -#else - retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7, - BLOCK_WRITE, WAIT_INT, data, 7, &val); -#endif - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - return STATUS_SUCCESS; -} - -static int ms_erase_block(struct rts51x_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i = 0; - u8 val = 0, data[6]; - - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, - 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (phy_blk >> 8); - data[3] = (u8) phy_blk; - data[4] = 0; - data[5] = 0; - -ERASE_RTY: -#ifdef MS_SPEEDUP - retval = - ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, - BLOCK_ERASE, WAIT_INT, data, 6, &val); -#else - retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, - BLOCK_ERASE, WAIT_INT, data, 6, &val); -#endif - - 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); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, 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 == setPS_NG) - extra[0] = 0xB8; - else - extra[0] = 0x98; - - extra[2] = (u8) (log_blk >> 8); - extra[3] = (u8) log_blk; -} - -static int ms_init_page(struct rts51x_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 (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, STATUS_FAIL); - - retval = - ms_write_extra_data(chip, phy_blk, i, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int ms_copy_page(struct rts51x_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); - int retval, rty_cnt, uncorrect_flag = 0; - u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; - - RTS51X_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n", - old_blk, new_blk, log_blk); - RTS51X_DEBUGP("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) - TRACE_RET(chip, retval); - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_READ_REG(chip, PPBUF_BASE2, &val); - - if (val & BUF_FULL) { - /* Clear Buffer */ - retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* GET_INT Register */ - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - for (i = start_page; i < end_page; i++) { - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, STATUS_FAIL); - - ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); - - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, - SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Write REG */ - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - 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) - TRACE_RET(chip, retval); - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { - uncorrect_flag = 1; - RTS51X_DEBUGP("Uncorrectable error\n"); - } else { - uncorrect_flag = 0; - } - - retval = - ms_transfer_tpc(chip, MS_TM_NORMAL_READ, - READ_PAGE_DATA, 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (uncorrect_flag) { - ms_set_page_status(log_blk, setPS_NG, - extra, MS_EXTRA_SIZE); - if (i == 0) - extra[0] &= 0xEF; - ms_write_extra_data(chip, old_blk, i, - extra, - MS_EXTRA_SIZE); - RTS51X_DEBUGP("page %d : extra[0] = 0x%x\n", - i, extra[0]); - MS_SET_BAD_BLOCK_FLG(ms_card); - - ms_set_page_status(log_blk, setPS_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) - TRACE_RET(chip, STATUS_FAIL); - } - - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, - MS_EXTRA_SIZE, SystemParm, - (6 + MS_EXTRA_SIZE)); - - /* Write REG */ - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (new_blk >> 8); - data[3] = (u8) new_blk; - data[4] = 0x20; - data[5] = i; - - /* for MS check procedure */ - 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) - TRACE_RET(chip, retval); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* GET_INT Register */ - 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) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (i == 0) { - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, - MS_EXTRA_SIZE, SystemParm, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - 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) - TRACE_RET(chip, retval); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, - MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - } - - return STATUS_SUCCESS; -} - -#ifdef MS_SPEEDUP -static int ms_auto_copy_page(struct rts51x_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); - int retval; - u8 page_len, bus_width, val = 0; - u8 extra[MS_EXTRA_SIZE]; - - RTS51X_DEBUGP("Auto copy page from 0x%x to 0x%x, logical block is 0x%x\n", - old_blk, new_blk, log_blk); - RTS51X_DEBUGP("start_page = %d, end_page = %d\n", start_page, - end_page); - - page_len = end_page - start_page; - - retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_READ_REG(chip, PPBUF_BASE2, &val); - - if (val & BUF_FULL) { - retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - bus_width = 0x88; - } else { - /* Serial interface */ - bus_width = 0x80; - } - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_OLD_BLOCK_0, 0xFF, (u8) old_blk); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_OLD_BLOCK_1, 0xFF, - (u8) (old_blk >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_NEW_BLOCK_0, 0xFF, (u8) new_blk); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_NEW_BLOCK_1, 0xFF, - (u8) (new_blk >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_LOG_BLOCK_0, 0xFF, (u8) log_blk); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_LOG_BLOCK_1, 0xFF, - (u8) (log_blk >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_PAGE_START, 0xFF, start_page); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_PAGE_LENGTH, 0xFF, page_len); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BUS_WIDTH, 0xFF, bus_width); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_COPY_PAGE); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) { - rts51x_clear_ms_error(chip); - TRACE_RET(chip, retval); - } - - retval = rts51x_get_rsp(chip, 1, 5000); - - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - rts51x_clear_ms_error(chip); - if (retval == STATUS_TIMEDOUT) - TRACE_RET(chip, retval); - TRACE_GOTO(chip, Fail); - } - - return STATUS_SUCCESS; - -Fail: - retval = ms_erase_block(chip, new_blk); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - ms_copy_page(chip, old_blk, new_blk, log_blk, start_page, end_page); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} -#endif - -static int reset_ms(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u16 i, reg_addr, block_size; - u8 val, j, *ptr; -#ifndef SUPPORT_MAGIC_GATE - u16 eblock_cnt; -#endif - - retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ms_card->ms_type |= TYPE_MS; - - retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_READ_REG(chip, PPBUF_BASE2, &val); - if (val & WRT_PRTCT) - chip->card_wp |= MS_CARD; - else - chip->card_wp &= ~MS_CARD; - - i = 0; - -RE_SEARCH: - /* Search For Boot Block */ - while (i < (MAX_DEFECTIVE_BLOCK + 2)) { - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_check_boot_block(chip, i); - if (retval != STATUS_SUCCESS) { - i++; - continue; - } - - ms_card->boot_block = i; - break; - } - - if (i == (MAX_DEFECTIVE_BLOCK + 2)) { - RTS51X_DEBUGP("No boot block found!"); - TRACE_RET(chip, 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; - } - } - } - - /* Read boot block contents */ - retval = ms_read_page(chip, ms_card->boot_block, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Read MS system information as sys_info */ - retval = - rts51x_seq_read_register(chip, PPBUF_BASE2 + 0x1A0, 96, - ms_card->raw_sys_info); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Read useful block contents */ - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); - rts51x_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); - - for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; - reg_addr++) { - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - } - - for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - rts51x_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0); - rts51x_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 16, 100); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ptr = rts51x_get_rsp_data(chip); - - RTS51X_DEBUGP("Boot block data:\n"); - RTS51X_DUMP(ptr, 16); - - if (ptr[0] != 0x00 || ptr[1] != 0x01) { - i = ms_card->boot_block + 1; - goto RE_SEARCH; - } - 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 = ((u16) ptr[6] << 8) | ptr[7]; - if (block_size == 0x0010) { - ms_card->block_shift = 5; - ms_card->page_off = 0x1F; - } else if (block_size == 0x0008) { - ms_card->block_shift = 4; - ms_card->page_off = 0x0F; - } - ms_card->total_block = ((u16) ptr[8] << 8) | ptr[9]; - -#ifdef SUPPORT_MAGIC_GATE - j = ptr[10]; - - if (ms_card->block_shift == 4) { - if (j < 2) - ms_card->capacity = 0x1EE0; - else - ms_card->capacity = 0x3DE0; - } else { - if (j < 5) - ms_card->capacity = 0x7BC0; - else if (j < 0xA) - ms_card->capacity = 0xF7C0; - else if (j < 0x11) - ms_card->capacity = 0x1EF80; - else - ms_card->capacity = 0x3DF00; - } -#else - 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; - - if (ptr[15]) { - retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - RTS51X_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88); - RTS51X_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0); - - retval = - ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG, 1, - NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - RTS51X_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT, - MS_BUS_WIDTH_4 | PUSH_TIME_ODD | - MS_NO_CHECK_INT); - - 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 rts51x_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; - RTS51X_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt); - - size = ms_card->segment_cnt * sizeof(struct zone_entry); - ms_card->segment = vmalloc(size); - if (ms_card->segment == NULL) - TRACE_RET(chip, STATUS_FAIL); - memset(ms_card->segment, 0, size); - - retval = ms_read_page(chip, ms_card->boot_block, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, INIT_FAIL); - - reg_addr = PPBUF_BASE2; - for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { - retval = rts51x_read_register(chip, reg_addr++, &val1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, INIT_FAIL); - retval = rts51x_read_register(chip, reg_addr++, &val2); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, INIT_FAIL); - - defect_block = ((u16) val1 << 8) | val2; - if (defect_block == 0xFFFF) - break; - seg_no = defect_block / 512; - ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no]. - disable_count++] = - 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; - - RTS51X_DEBUGP("defective block count of segment %d is %d\n", - i, ms_card->segment[i].disable_count); - } - - return STATUS_SUCCESS; - -INIT_FAIL: - if (ms_card->segment) { - vfree(ms_card->segment); - ms_card->segment = NULL; - } - - return STATUS_FAIL; -} - -static u16 ms_get_l2p_tbl(struct rts51x_chip *chip, int seg_no, u16 log_off) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - - if (ms_card->segment == NULL) - 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 rts51x_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 == NULL) - 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 rts51x_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 rts51x_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 rts51x_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 rts51x_chip *chip, int seg_no) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - int retval, table_size, disable_cnt, defect_flag, i; - u16 start, end, phy_blk, log_blk, tmp_blk; - u8 extra[MS_EXTRA_SIZE], us1, us2; - - RTS51X_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no); - - if (ms_card->segment == NULL) { - retval = ms_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - if (ms_card->segment[seg_no].build_flag) { - RTS51X_DEBUGP("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 == NULL) { - segment->l2p_table = vmalloc(table_size * 2); - if (segment->l2p_table == NULL) - TRACE_GOTO(chip, BUILD_FAIL); - } - memset((u8 *) (segment->l2p_table), 0xff, table_size * 2); - - if (segment->free_table == NULL) { - segment->free_table = vmalloc(MS_FREE_TABLE_CNT * 2); - if (segment->free_table == NULL) - TRACE_GOTO(chip, BUILD_FAIL); - } - memset((u8 *) (segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2); - - start = (u16) seg_no << 9; - end = (u16) (seg_no + 1) << 9; - - disable_cnt = segment->disable_count; - - segment->get_index = segment->set_index = 0; - segment->unused_blk_cnt = 0; - - for (phy_blk = start; phy_blk < end; phy_blk++) { - if (disable_cnt) { - defect_flag = 0; - for (i = 0; i < segment->disable_count; i++) { - if (phy_blk == segment->defect_list[i]) { - defect_flag = 1; - break; - } - } - if (defect_flag) { - disable_cnt--; - continue; - } - } - - retval = - ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { - RTS51X_DEBUGP("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; - } - - if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == - 0xFFFF) { - segment->l2p_table[log_blk - ms_start_idx[seg_no]] = - phy_blk; - continue; - } - - us1 = extra[0] & 0x10; - tmp_blk = segment->l2p_table[log_blk - ms_start_idx[seg_no]]; - 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); - continue; - } - - segment->build_flag = 1; - - RTS51X_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt); - - 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++) { - if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == - 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) - TRACE_GOTO(chip, BUILD_FAIL); - segment->l2p_table[log_blk - ms_start_idx[seg_no]] = - 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; - } - } - } - } - - 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) { - RTS51X_DEBUGP("Boot block is not the first normal block.\n"); - - if (chip->card_wp & MS_CARD) - break; - - phy_blk = ms_get_unused_block(chip, 0); -#ifdef MS_SPEEDUP - retval = - ms_auto_copy_page(chip, tmp_blk, phy_blk, - log_blk, 0, - ms_card->page_off + 1); -#else - retval = ms_copy_page(chip, tmp_blk, phy_blk, - log_blk, 0, - ms_card->page_off + 1); -#endif - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - segment->l2p_table[log_blk] = phy_blk; - - retval = ms_set_bad_block(chip, tmp_blk); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - } - } - - return STATUS_SUCCESS; - -BUILD_FAIL: - segment->build_flag = 0; - if (segment->l2p_table) { - vfree(segment->l2p_table); - segment->l2p_table = NULL; - } - if (segment->free_table) { - vfree(segment->free_table); - segment->free_table = NULL; - } - - return STATUS_FAIL; -} - -int rts51x_reset_ms_card(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - memset(ms_card, 0, sizeof(struct ms_info)); - - rts51x_enable_card_clock(chip, MS_CARD); - - retval = rts51x_select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ms_card->ms_type = 0; - ms_card->last_rw_int = 0; - - retval = reset_ms_pro(chip); - if (retval != STATUS_SUCCESS) { - if (ms_card->check_ms_flow) { - retval = reset_ms(chip); - if (retval != STATUS_SUCCESS) { - if (chip->option.reset_or_rw_fail_set_pad_drive) { - rts51x_write_register(chip, - CARD_DRIVE_SEL, SD20_DRIVE_MASK, - DRIVE_8mA); - } - TRACE_RET(chip, retval); - } - } else { - if (chip->option.reset_or_rw_fail_set_pad_drive) { - rts51x_write_register(chip, CARD_DRIVE_SEL, - SD20_DRIVE_MASK, - DRIVE_8mA); - } - TRACE_RET(chip, retval); - } - } - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (!CHK_MSPRO(ms_card)) { - retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - RTS51X_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type); - - return STATUS_SUCCESS; -} - -static int mspro_set_rw_cmd(struct rts51x_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) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static void mspro_stop_seq_mode(struct rts51x_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_card->last_rw_int = 0; - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - - rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, - FIFO_FLUSH); - } -} - -static inline int ms_auto_tune_clock(struct rts51x_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) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int mspro_rw_multi_sector(struct scsi_cmnd *srb, - struct rts51x_chip *chip, u32 start_sector, - u16 sector_cnt) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, mode_2k = 0; - u16 count; - u8 val, trans_mode, rw_tpc, rw_cmd; - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->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 = 1; - } - } 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) - TRACE_RET(chip, retval); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) - trans_mode = MS_TM_AUTO_READ; - else - trans_mode = MS_TM_AUTO_WRITE; - - val = ms_card->last_rw_int; - - 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; - ms_card->last_rw_int = 0; - if (val & MS_INT_BREQ) { - retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - rts51x_ep0_write_register(chip, MC_FIFO_CTL, - FIFO_FLUSH, FIFO_FLUSH); - } - } - } - - if (!ms_card->seq_mode) { - ms_card->total_sec_cnt = 0; - if (sector_cnt >= 0x80) { - 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; - TRACE_RET(chip, retval); - } - } - - 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; - rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); - rts51x_clear_ms_error(chip); - if (val & MS_INT_BREQ) - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - RTS51X_DEBUGP("MSPro CRC error, tune clock!\n"); - ms_auto_tune_clock(chip); - } - - TRACE_RET(chip, retval); - } - - 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 rts51x_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]; - - ms_card->format_status = FORMAT_FAIL; - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); - - if ((tmp & (MS_INT_CED | MS_INT_CMDNK | MS_INT_ERR)) == MS_INT_CED) { - ms_card->format_status = FORMAT_SUCCESS; - ms_card->pro_under_formatting = 0; - return STATUS_SUCCESS; - } - if (! - ((tmp & (MS_INT_BREQ | MS_INT_CED | MS_INT_CMDNK | MS_INT_ERR)) == - MS_INT_BREQ)) { - ms_card->pro_under_formatting = 0; - TRACE_RET(chip, STATUS_FAIL); - } - - if (short_data_len >= 256) - cnt = 0; - else - cnt = (u8) short_data_len; - - retval = - ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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]; - - RTS51X_DEBUGP("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; - } - RTS51X_DEBUGP("progress = %d\n", ms_card->progress); - - for (i = 0; i < 2500; i++) { - RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); - if (tmp & - (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) - break; - - wait_timeout(1); - } - - if (i == 2500) - TRACE_RET(chip, STATUS_FAIL); - - RTS51X_DEBUGP("MSPro format tmp:%d\n", tmp); - - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) - TRACE_RET(chip, 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; - TRACE_RET(chip, STATUS_FAIL); - } - - RTS51X_DEBUGP("MSPro format format_status:%d\n", - ms_card->format_status); - - return STATUS_SUCCESS; -} - -void rts51x_mspro_polling_format_status(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int i; - - if (ms_card->pro_under_formatting) { - for (i = 0; i < 65535; i++) { - mspro_read_format_progress(chip, MS_SHORT_DATA_LEN); - if (ms_card->format_status != FORMAT_IN_PROGRESS) - break; - } - } - - return; -} - -void rts51x_mspro_format_sense(struct rts51x_chip *chip, unsigned int lun) -{ - struct ms_info *ms_card = &(chip->ms_card); - - if (CHK_FORMAT_STATUS(ms_card, FORMAT_SUCCESS)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } else if (CHK_FORMAT_STATUS(ms_card, FORMAT_IN_PROGRESS)) { - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16) (ms_card->progress)); - } else { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } -} - -int rts51x_mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, - int short_data_len, int 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) - TRACE_RET(chip, retval); - - retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, STATUS_FAIL); - /* Format command */ - if (quick_format) - para = 0x0000; - else - para = 0x0001; - retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Check INT */ - RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) - TRACE_RET(chip, 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; - rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); - return STATUS_SUCCESS; - } - - TRACE_RET(chip, STATUS_FAIL); -} - -#ifdef MS_SPEEDUP -static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk, - u16 log_blk, u8 start_page, u8 end_page, - u8 *buf, void **ptr, unsigned int *offset) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - int send_blkend; - u8 extra[MS_EXTRA_SIZE], val1, val2, data[6]; - u8 page_cnt = end_page - start_page, page_addr, sec_cnt; - - if (end_page != (ms_card->page_off + 1)) - send_blkend = 1; - else - send_blkend = 0; - - 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); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (phy_blk >> 8); - data[3] = (u8) phy_blk; - /* Page Number - * Extra data access mode */ - data[4] = 0; - data[5] = start_page; - - retval = - ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, - BLOCK_READ, WAIT_INT, data, 6, &val1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - rts51x_init_cmd(chip); - - if (send_blkend) - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, - SET_BLKEND); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, WAIT_INT, - NO_WAIT_INT); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, - (u8) page_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); - - rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, 512 * page_cnt, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_MULTI_READ); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDIR | STAGE_MS_STATUS, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - rts51x_transfer_data_partial(chip, RCV_BULK_PIPE(chip), (void *)buf, - ptr, offset, 512 * page_cnt, - scsi_sg_count(chip->srb), NULL, 2000); - if (retval != STATUS_SUCCESS) { - rts51x_clear_ms_error(chip); - if (retval == STATUS_TIMEDOUT) - TRACE_RET(chip, retval); - TRACE_GOTO(chip, Fail); - } - retval = rts51x_get_rsp(chip, 3, 200); - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - rts51x_clear_ms_error(chip); - if (retval == STATUS_TIMEDOUT) - TRACE_RET(chip, retval); - TRACE_GOTO(chip, Fail); - } - - return STATUS_SUCCESS; - -Fail: - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, READ_REG_CMD, MS_SECTOR_CNT_L, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR | STAGE_MS_STATUS, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 3, 200); - - if (CHECK_MS_TRANS_FAIL(chip, retval)) - TRACE_RET(chip, STATUS_FAIL); - - sec_cnt = chip->rsp_buf[0]; - RTS51X_DEBUGP("%d pages need be transferred, %d pages remained\n", - (int)page_cnt, (int)sec_cnt); - page_addr = start_page + (page_cnt - sec_cnt); - - if (CHK_MS4BIT(ms_card)) { - val1 = chip->rsp_buf[1]; - RTS51X_DEBUGP("MS_TRANS_CFG: 0x%x\n", val1); - } else { - val1 = 0; - } - - val2 = chip->rsp_buf[2]; - RTS51X_DEBUGP("GET_INT: 0x%x\n", val2); - - if ((val1 & INT_CMDNK) || (val2 & INT_REG_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if ((val1 & INT_ERR) || (val2 & INT_REG_ERR)) { - if ((val1 & INT_BREQ) || (val2 & 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, setPS_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); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - if (CHK_MS4BIT(ms_card)) { - if (!(val1 & INT_BREQ) && !(val2 & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - if (!(val2 & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk, - u16 new_blk, u16 log_blk, u8 start_page, - u8 end_page, u8 *buf, void **ptr, - unsigned int *offset) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - int send_blkend; - u8 val, data[16]; - u8 page_cnt = end_page - start_page; - - if ((end_page == (ms_card->page_off + 1)) || (page_cnt == 1)) - send_blkend = 0; - else - send_blkend = 1; - - if (!start_page) { - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - 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_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, - SystemParm, 7, BLOCK_WRITE, WAIT_INT, data, - 7, &val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, - (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (new_blk >> 8); - data[3] = (u8) new_blk; - /* Page Number - * Extra data access mode */ - if (page_cnt == 1) { - /* Single page access mode */ - data[4] = 0x20; - } else { - /* Block access mode */ - 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++) { - /* ECC */ - data[i] = 0xFF; - } - - retval = - ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, - (6 + MS_EXTRA_SIZE), BLOCK_WRITE, WAIT_INT, data, - 16, &val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - rts51x_init_cmd(chip); - - if (send_blkend) - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, - SET_BLKEND); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, WAIT_INT, - NO_WAIT_INT); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, - (u8) page_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, WRITE_PAGE_DATA); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - RING_BUFFER); - - rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512 * page_cnt, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_MULTI_WRITE); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, - MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDOR | STAGE_MS_STATUS, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - rts51x_transfer_data_partial(chip, SND_BULK_PIPE(chip), (void *)buf, - ptr, offset, 512 * page_cnt, - scsi_sg_count(chip->srb), NULL, 2000); - if (retval != STATUS_SUCCESS) { - rts51x_clear_ms_error(chip); - TRACE_RET(chip, retval); - } - - retval = rts51x_get_rsp(chip, 3, 2000); - - - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - rts51x_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -#else - -static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk, - u16 log_blk, u8 start_page, u8 end_page, - u8 *buf, void **ptr, 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]; - - 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); - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, - 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Write REG */ - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (phy_blk >> 8); - data[3] = (u8) phy_blk; - /* Page Number - * Extra data access mode */ - 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) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { - ms_set_err_code(chip, MS_NO_CARD); - chip->card_exist &= ~MS_CARD; - chip->card_ready &= ~MS_CARD; - TRACE_RET(chip, STATUS_FAIL); - } - /* GET_INT Register */ - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, 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, - setPS_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); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, 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) - TRACE_RET(chip, retval); - } - retval = - ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, - 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - trans_cfg = NO_WAIT_INT; - } else { - trans_cfg = WAIT_INT; - } - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, - READ_PAGE_DATA); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, - trans_cfg); - - rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_READ); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDIR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - rts51x_transfer_data_partial(chip, RCV_BULK_PIPE(chip), - (void *)buf, ptr, offset, 512, - scsi_sg_count(chip->srb), NULL, - 2000); - if (retval != STATUS_SUCCESS) { - if (retval == STATUS_TIMEDOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, retval); - } - - retval = - rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_TO_ERROR); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - ms_set_err_code(chip, MS_CRC16_ERROR); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = rts51x_get_rsp(chip, 1, 2000); - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - if (retval == STATUS_TIMEDOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, retval); - } - - retval = - rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_TO_ERROR); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, retval); - } - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - ms_set_err_code(chip, MS_CRC16_ERROR); - rts51x_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - return STATUS_SUCCESS; -} - -static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk, - u16 new_blk, u16 log_blk, u8 start_page, - u8 end_page, u8 *buf, void **ptr, - unsigned int *offset) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 page_addr, val, data[16]; - - if (!start_page) { - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, - SystemParm, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - 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) - TRACE_RET(chip, retval); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* GET_INT Register */ - 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) - TRACE_RET(chip, retval); - } - - retval = - ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, - (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - /* Block Address */ - data[1] = 0; - data[2] = (u8) (new_blk >> 8); - data[3] = (u8) new_blk; - /* Page Number - * Extra data access mode */ - if ((end_page - start_page) == 1) { - /* Single page access mode */ - data[4] = 0x20; - } else { - /* Block access mode */ - 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++) { - /* ECC */ - 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) - TRACE_RET(chip, 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) - TRACE_RET(chip, STATUS_FAIL); - /* GET_INT Register */ - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - udelay(30); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, - WRITE_PAGE_DATA); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, - WAIT_INT); - - rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDOR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - rts51x_transfer_data_partial(chip, SND_BULK_PIPE(chip), - (void *)buf, ptr, offset, 512, - scsi_sg_count(chip->srb), NULL, - 2000); - if (retval != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_TO_ERROR); - rts51x_clear_ms_error(chip); - - if (retval == STATUS_TIMEDOUT) - TRACE_RET(chip, STATUS_TIMEDOUT); - else - TRACE_RET(chip, STATUS_FAIL); - } - - retval = rts51x_get_rsp(chip, 1, 2000); - if (CHECK_MS_TRANS_FAIL(chip, retval)) { - ms_set_err_code(chip, MS_TO_ERROR); - rts51x_clear_ms_error(chip); - - if (retval == STATUS_TIMEDOUT) - TRACE_RET(chip, STATUS_TIMEDOUT); - else - TRACE_RET(chip, STATUS_FAIL); - } - /* GET_INT Register */ - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if ((end_page - start_page) == 1) { - if (!(val & INT_REG_CED)) { - /* Command can not be executed */ - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, 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) - TRACE_RET(chip, retval); - } - /* GET_INT Register */ - retval = - ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, - &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - 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); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - } - - return STATUS_SUCCESS; -} -#endif - -static int ms_finish_write(struct rts51x_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; - -#ifdef MS_SPEEDUP - retval = ms_auto_copy_page(chip, old_blk, new_blk, log_blk, - page_off, ms_card->page_off + 1); -#else - retval = ms_copy_page(chip, old_blk, new_blk, log_blk, - page_off, ms_card->page_off + 1); -#endif - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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 rts51x_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page) -{ - int retval; - - if (start_page) { -#ifdef MS_SPEEDUP - retval = - ms_auto_copy_page(chip, old_blk, new_blk, log_blk, 0, - start_page); -#else - retval = - ms_copy_page(chip, old_blk, new_blk, log_blk, 0, - start_page); -#endif - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -int rts51x_ms_delay_write(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct rts51x_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) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static inline void rts51x_ms_rw_fail(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - if (srb->sc_data_direction == DMA_FROM_DEVICE) - rts51x_set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); -} - -static int rts51x_ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_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 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 *buf; - void *ptr = NULL; - struct rts51x_ms_delay_write_tag *delay_write = &(ms_card->delay_write); - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->counter = 0; - - buf = (u8 *) scsi_sglist(srb); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - rts51x_ms_rw_fail(srb, chip); - TRACE_RET(chip, retval); - } - - 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; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, retval); - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page > delay_write->pageoff)) { - delay_write->delay_write_flag = 0; -#ifdef MS_SPEEDUP - retval = ms_auto_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - log_blk, - delay_write->pageoff, - start_page); -#else - retval = ms_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - log_blk, delay_write->pageoff, - start_page); -#endif - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, retval); - } - 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 = rts51x_ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, retval); - } - 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)) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = - ms_prepare_write(chip, old_blk, new_blk, log_blk, - start_page); - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, MS_CARD) == - CD_NOT_EXIST) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, retval); - } - } - } else { - retval = rts51x_ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, retval); - } - old_blk = - ms_get_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTS51X_DEBUGP("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; - - RTS51X_DEBUGP("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, - buf, &ptr, &offset); - else - retval = ms_write_multiple_pages(chip, old_blk, - new_blk, log_blk, - start_page, end_page, - buf, &ptr, &offset); - - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_ms_rw_fail(srb, chip); - TRACE_RET(chip, retval); - } - /* Update L2P table if need */ - 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 (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; - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, retval); - } - } - - old_blk = - ms_get_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - rts51x_ms_rw_fail(srb, chip); - TRACE_RET(chip, STATUS_FAIL); - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - new_blk = ms_get_unused_block(chip, seg_no); - if (new_blk == 0xFFFF) { - rts51x_ms_rw_fail(srb, chip); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTS51X_DEBUGP("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)) { - 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; - } - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -int rts51x_ms_rw(struct scsi_cmnd *srb, struct rts51x_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 = - rts51x_ms_rw_multi_sector(srb, chip, start_sector, sector_cnt); - - return retval; -} - -void rts51x_ms_free_l2p_tbl(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int i = 0; - - if (ms_card->segment != NULL) { - for (i = 0; i < ms_card->segment_cnt; i++) { - if (ms_card->segment[i].l2p_table != NULL) { - vfree(ms_card->segment[i].l2p_table); - ms_card->segment[i].l2p_table = NULL; - } - if (ms_card->segment[i].free_table != NULL) { - vfree(ms_card->segment[i].free_table); - ms_card->segment[i].free_table = NULL; - } - } - vfree(ms_card->segment); - ms_card->segment = NULL; - } -} - -void rts51x_ms_cleanup_work(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - RTS51X_DEBUGP("MS Pro: stop transmission\n"); - mspro_stop_seq_mode(chip); - ms_card->counter = 0; - } - if (CHK_MSHG(ms_card)) { - u8 value; - rts51x_read_register(chip, MS_CFG, &value); - if (value & MS_2K_SECTOR_MODE) - rts51x_write_register(chip, MS_CFG, - MS_2K_SECTOR_MODE, 0x00); - } - } else if ((!CHK_MSPRO(ms_card)) - && ms_card->delay_write.delay_write_flag) { - RTS51X_DEBUGP("MS: delay write\n"); - rts51x_ms_delay_write(chip); - ms_card->counter = 0; - } -} - -static int ms_power_off_card3v3(struct rts51x_chip *chip) -{ - int retval; - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0); - if (chip->asic_code) - ms_pull_ctl_disable(chip); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, - FPGA_MS_PULL_CTL_BIT | 0x20, - FPGA_MS_PULL_CTL_BIT); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); - if (!chip->option.FT2_fast_mode) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - } - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_release_ms_card(struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - RTS51X_DEBUGP("rts51x_release_ms_card\n"); - - ms_card->delay_write.delay_write_flag = 0; - ms_card->pro_under_formatting = 0; - - chip->card_ready &= ~MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->card_wp &= ~MS_CARD; - - rts51x_ms_free_l2p_tbl(chip); - - rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); - - 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) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h deleted file mode 100644 index 857c1974ef24..000000000000 --- a/drivers/staging/rts5139/ms.h +++ /dev/null @@ -1,261 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_MS_H -#define __RTS51X_MS_H - -#include "rts51x_chip.h" - -#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 - -/* ++ CMD over Memory Stick */ -/* Flash CMD */ -#define BLOCK_READ 0xAA -#define BLOCK_WRITE 0x55 -#define BLOCK_END 0x33 -#define BLOCK_ERASE 0x99 -#define FLASH_STOP 0xCC - -/* Function CMD */ -#define SLEEP 0x5A -#define CLEAR_BUF 0xC3 -#define MS_RESET 0x3C -/* -- CMD over Memory Stick */ - -/* ++ CMD over Memory Stick Pro */ -/* Flash CMD */ -#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 - -/* Function CMD */ -#define PRO_FORMAT 0x10 -#define PRO_SLEEP 0x11 -/* -- CMD over Memory Stick Pro */ - -/* register inside memory stick */ -#define IntReg 0x01 -#define StatusReg0 0x02 -#define StatusReg1 0x03 - -#define SystemParm 0x10 -#define BlockAdrs 0x11 -#define CMDParm 0x14 -#define PageAdrs 0x15 - -#define OverwriteFlag 0x16 -#define ManagemenFlag 0x17 -#define LogicalAdrs 0x18 -#define ReserveArea 0x1A - -/* register inside memory pro */ -#define Pro_IntReg 0x01 -#define Pro_StatusReg 0x02 -#define Pro_TypeReg 0x04 -#define Pro_IFModeReg 0x05 -#define Pro_CatagoryReg 0x06 -#define Pro_ClassReg 0x07 - -#define Pro_SystemParm 0x10 -#define Pro_DataCount1 0x11 -#define Pro_DataCount0 0x12 -#define Pro_DataAddr3 0x13 -#define Pro_DataAddr2 0x14 -#define Pro_DataAddr1 0x15 -#define Pro_DataAddr0 0x16 - -#define Pro_TPCParm 0x17 -#define Pro_CMDParm 0x18 - -/* define for INT Register */ -#define INT_REG_CED 0x80 -#define INT_REG_ERR 0x40 -#define INT_REG_BREQ 0x20 -#define INT_REG_CMDNK 0x01 - -/* INT signal */ -#define INT_CED 0x01 -#define INT_ERR 0x02 -#define INT_BREQ 0x04 -#define INT_CMDNK 0x08 - -/* define for OverwriteFlag Register */ -#define BLOCK_BOOT 0xC0 -#define BLOCK_OK 0x80 -#define PAGE_OK 0x60 -#define DATA_COMPL 0x10 - -/* define for ManagemenFlag Register */ -#define NOT_BOOT_BLOCK 0x4 -#define NOT_TRANSLATION_TABLE 0x8 - -/* Header */ -#define HEADER_ID0 (PPBUF_BASE2) /* 0 */ -#define HEADER_ID1 (PPBUF_BASE2 + 1) /* 1 */ -/* System Entry */ -#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4) /* 2 */ -#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5) /* 3 */ -#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6) /* 4 */ -#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7) /* 5 */ -/* Boot & Attribute Information */ -#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2) /* 6 */ -#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3) /* 7 */ -#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4) /* 8 */ -#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5) /* 9 */ -#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6) /* 10 */ -#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7) /* 11 */ -#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8) /* 12 */ -#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9) /* 13 */ - -/* joey 2004-08-07 for MS check Procedure */ -#define MS_Device_Type (PPBUF_BASE2 + 0x1D8) /* 14 */ -/* end */ - -/* joey 2004-05-03 */ -#define MS_4bit_Support (PPBUF_BASE2 + 0x1D3) /* 15 */ -/* end */ - -#define setPS_NG 1 -#define setPS_Error 0 - -/* define for Pro_SystemParm Register */ -#define PARALLEL_8BIT_IF 0x40 -#define PARALLEL_4BIT_IF 0x00 -#define SERIAL_IF 0x80 - -/* define for StatusReg0 Register */ -#define BUF_FULL 0x10 -#define BUF_EMPTY 0x20 - -/* define for StatusReg1 Register */ -#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) - -#define CHECK_MS_TRANS_FAIL(chip, retval) \ - (((retval) != STATUS_SUCCESS) || \ - (chip->rsp_buf[0] & MS_TRANSFER_ERR)) - -void rts51x_mspro_polling_format_status(struct rts51x_chip *chip); -void rts51x_mspro_format_sense(struct rts51x_chip *chip, unsigned int lun); - -int rts51x_reset_ms_card(struct rts51x_chip *chip); -int rts51x_ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, - u16 sector_cnt); -int rts51x_mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, - int short_data_len, int quick_format); -void rts51x_ms_free_l2p_tbl(struct rts51x_chip *chip); -void rts51x_ms_cleanup_work(struct rts51x_chip *chip); -int rts51x_release_ms_card(struct rts51x_chip *chip); -int rts51x_ms_delay_write(struct rts51x_chip *chip); - -#ifdef SUPPORT_MAGIC_GATE - -int ms_switch_clock(struct rts51x_chip *chip); -int ms_write_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, - int data_len); -int ms_read_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, - int data_len); -int ms_set_rw_reg_addr(struct rts51x_chip *chip, u8 read_start, u8 read_cnt, - u8 write_start, u8 write_cnt); -int ms_transfer_data(struct rts51x_chip *chip, u8 trans_mode, u8 tpc, - u16 sec_cnt, u8 cfg, int mode_2k, int use_sg, void *buf, - int buf_len); -#endif - -#endif /* __RTS51X_MS_H */ diff --git a/drivers/staging/rts5139/ms_mg.c b/drivers/staging/rts5139/ms_mg.c deleted file mode 100644 index c8f26062c682..000000000000 --- a/drivers/staging/rts5139/ms_mg.c +++ /dev/null @@ -1,643 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include "debug.h" -#include "trace.h" -#include "rts51x.h" -#include "rts51x_transport.h" -#include "rts51x_scsi.h" -#include "rts51x_card.h" -#include "ms.h" -#include "ms_mg.h" - -#ifdef SUPPORT_MAGIC_GATE - -static int mg_check_int_error(struct rts51x_chip *chip) -{ - u8 value; - - rts51x_read_register(chip, MS_TRANS_CFG, &value); - if (value & (INT_ERR | INT_CMDNK)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int mg_send_ex_cmd(struct rts51x_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) - TRACE_RET(chip, STATUS_FAIL); - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int rts51x_mg_set_tpc_para_sub(struct rts51x_chip *chip, int type, u8 mg_entry_num) -{ - int retval; - u8 buf[6]; - - RTS51X_DEBUGP("--%s--\n", __func__); - - if (type == 0) - retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1); - else - retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -/** - * Get MagciGate ID and set Leaf ID to medium. - - * After receiving this SCSI command, adapter shall fulfill 2 tasks - * below in order: - * 1. send GET_ID TPC command to get MagicGate ID and hold it till - * Response&challenge CMD. - * 2. send SET_ID TPC command to medium with Leaf ID released by host - * in this SCSI CMD. - */ -int rts51x_mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int retval; - int i; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[12]; - - RTS51X_DEBUGP("--%s--\n", __func__); - - if (scsi_bufflen(srb) < 12) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, STATUS_FAIL); - } - rts51x_ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - TRACE_RET(chip, retval); - } - - memset(buf1, 0, 32); - rts51x_get_xfer_buf(buf2, min(12, (int)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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - TRACE_RET(chip, retval); - } - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -/** - * Send Local EKB to host. - - * After receiving this SCSI command, adapter shall read the divided - * data(1536 bytes totally) from medium by using READ_LONG_DATA TPC - * for 3 times, and report data to host with data-length is 1052 bytes. - */ -int rts51x_mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int retval = STATUS_FAIL; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - RTS51X_DEBUGP("--%s--\n", __func__); - - rts51x_ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - buf = kmalloc(1540, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_NOMEM); - - 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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_GOTO(chip, GetEKBFinish); - } - - 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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, - MS_STOP | MS_CLR_ERR); - TRACE_GOTO(chip, GetEKBFinish); - } - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_GOTO(chip, GetEKBFinish); - } - - bufflen = min(1052, (int)scsi_bufflen(srb)); - rts51x_set_xfer_buf(buf, bufflen, srb); - -GetEKBFinish: - kfree(buf); - return retval; -} - -/** - * Send challenge(host) to medium. - - * After receiving this SCSI command, adapter shall sequentially issues - * TPC commands to the medium for writing 8-bytes data as challenge - * by host within a short data packet. - */ -int rts51x_mg_chg(struct scsi_cmnd *srb, struct rts51x_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], tmp; - - RTS51X_DEBUGP("--%s--\n", __func__); - - rts51x_ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, retval); - } - - retval = - ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf, 32); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, retval); - } - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, retval); - } - - memcpy(ms_card->magic_gate_id, buf, 16); - - for (i = 0; i < 2500; i++) { - RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); - if (tmp & - (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) - break; - - wait_timeout(1); - } - - if (i == 2500) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, retval); - } - - bufflen = min(12, (int)scsi_bufflen(srb)); - rts51x_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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, retval); - } - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, retval); - } - - ms_card->mg_auth = 0; - - return STATUS_SUCCESS; -} - -/** - * Send Response and Challenge data to host. - - * After receiving this SCSI command, adapter shall communicates with - * the medium, get parameters(HRd, Rms, MagicGateID) by using READ_SHORT_DATA - * TPC and send the data to host according to certain format required by - * MG-R specification. - * The paremeter MagicGateID is the one that adapter has obtained from - * the medium by TPC commands in Set Leaf ID command phase previously. - */ -int rts51x_mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[36], tmp; - - RTS51X_DEBUGP("--%s--\n", __func__); - - rts51x_ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, retval); - } - - retval = - ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf1, 32); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, retval); - } - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, retval); - } - - 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(36, (int)scsi_bufflen(srb)); - rts51x_set_xfer_buf(buf2, bufflen, srb); - - for (i = 0; i < 2500; i++) { - RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); - if (tmp & (MS_INT_CED | MS_INT_CMDNK | - MS_INT_BREQ | MS_INT_ERR)) - break; - - wait_timeout(1); - } - - if (i == 2500) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -/** - * Send response(host) to medium. - - * After receiving this SCSI command, adapter shall sequentially - * issues TPC commands to the medium for writing 8-bytes data as - * challenge by host within a short data packet. - */ -int rts51x_mg_rsp(struct scsi_cmnd *srb, struct rts51x_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]; - - RTS51X_DEBUGP("--%s--\n", __func__); - - rts51x_ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, retval); - } - - bufflen = min(12, (int)scsi_bufflen(srb)); - rts51x_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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, retval); - } - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, retval); - } - - ms_card->mg_auth = 1; - - return STATUS_SUCCESS; -} - -/** * Send ICV data to host. - - * After receiving this SCSI command, adapter shall read the divided - * data(1024 bytes totally) from medium by using READ_LONG_DATA TPC - * for 2 times, and report data to host with data-length is 1028 bytes. - * - * Since the extra 4 bytes data is just only a prefix to original data - * that read from medium, so that the 4-byte data pushed into Ring buffer - * precedes data transmission from medium to Ring buffer by DMA mechanism - * in order to get maximum performance and minimum code size simultaneously. - */ -int rts51x_mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - RTS51X_DEBUGP("--%s--\n", __func__); - - rts51x_ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_NOMEM); - - 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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_GOTO(chip, GetICVFinish); - } - - 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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, - MS_STOP | MS_CLR_ERR); - TRACE_GOTO(chip, GetICVFinish); - } - retval = mg_check_int_error(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_GOTO(chip, GetICVFinish); - } - - bufflen = min(1028, (int)scsi_bufflen(srb)); - rts51x_set_xfer_buf(buf, bufflen, srb); - -GetICVFinish: - kfree(buf); - return retval; -} - -/** - * Send ICV data to medium. - - * After receiving this SCSI command, adapter shall receive 1028 bytes - * and write the later 1024 bytes to medium by WRITE_LONG_DATA TPC - * consecutively. - * - * Since the first 4-bytes data is just only a prefix to original data - * that sent by host, and it should be skipped by shifting DMA pointer - * before writing 1024 bytes to medium. - */ -int rts51x_mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_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; - - RTS51X_DEBUGP("--%s--\n", __func__); - - rts51x_ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_NOMEM); - - bufflen = min(1028, (int)scsi_bufflen(srb)); - rts51x_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) - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - TRACE_GOTO(chip, SetICVFinish); - } - -#ifdef MG_SET_ICV_SLOW - for (i = 0; i < 2; i++) { - udelay(50); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, - PRO_WRITE_LONG_DATA); - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, - WAIT_INT); - - rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDOR, 100); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - TRACE_GOTO(chip, SetICVFinish); - } - - retval = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), - buf + 4 + i * 512, 512, 0, - NULL, 3000, STAGE_DO); - if (retval != STATUS_SUCCESS) { - rts51x_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } - retval = STATUS_FAIL; - TRACE_GOTO(chip, SetICVFinish); - } - - retval = rts51x_get_rsp(chip, 1, 3000); - if (CHECK_MS_TRANS_FAIL(chip, retval) - || mg_check_int_error(chip)) { - rts51x_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } - retval = STATUS_FAIL; - TRACE_GOTO(chip, SetICVFinish); - } - } -#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) { - rts51x_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - TRACE_GOTO(chip, SetICVFinish); - } -#endif - -SetICVFinish: - kfree(buf); - return retval; -} - -#endif /* SUPPORT_MAGIC_GATE */ diff --git a/drivers/staging/rts5139/ms_mg.h b/drivers/staging/rts5139/ms_mg.h deleted file mode 100644 index 109c71290953..000000000000 --- a/drivers/staging/rts5139/ms_mg.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_MS_MG_H -#define __RTS51X_MS_MG_H - -#include "rts51x_chip.h" -#include "ms.h" - -int rts51x_mg_set_tpc_para_sub(struct rts51x_chip *chip, int type, u8 mg_entry_num); -int rts51x_mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); - -#endif /* __RTS51X_MS_MG_H */ diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c deleted file mode 100644 index 8529cbabc554..000000000000 --- a/drivers/staging/rts5139/rts51x.c +++ /dev/null @@ -1,846 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "ms.h" -#include "rts51x.h" -#include "rts51x_chip.h" -#include "rts51x_card.h" -#include "rts51x_scsi.h" -#include "rts51x_transport.h" -#include "rts51x_fop.h" - -MODULE_DESCRIPTION(RTS51X_DESC); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); - -static int auto_delink_en; -module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); - -static int ss_en; -module_param(ss_en, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ss_en, "enable selective suspend"); - -static int ss_delay = 50; -module_param(ss_delay, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ss_delay, - "seconds to delay before entering selective suspend"); - -static int needs_remote_wakeup; -module_param(needs_remote_wakeup, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(needs_remote_wakeup, "ss state needs remote wakeup supported"); - -#ifdef SUPPORT_FILE_OP -static const struct file_operations rts51x_fops = { - .owner = THIS_MODULE, - .read = rts51x_read, - .write = rts51x_write, - .unlocked_ioctl = rts51x_ioctl, - .open = rts51x_open, - .release = rts51x_release, -}; - -/* - * usb class driver info in order to get a minor number from the usb core, - * and to have the device registered with the driver core - */ -static struct usb_class_driver rts51x_class = { - .name = "rts51x%d", - .fops = &rts51x_fops, - .minor_base = 192, -}; -#endif - -#ifdef CONFIG_PM /* Minimal support for suspend and resume */ - -static inline void usb_autopm_enable(struct usb_interface *intf) -{ - atomic_set(&intf->pm_usage_cnt, 1); - usb_autopm_put_interface(intf); -} - -static inline void usb_autopm_disable(struct usb_interface *intf) -{ - atomic_set(&intf->pm_usage_cnt, 0); - usb_autopm_get_interface(intf); -} - -static void rts51x_try_to_enter_ss(struct rts51x_chip *chip) -{ - pr_debug("Ready to enter SS state\n"); - usb_autopm_enable(chip->usb->pusb_intf); -} - -void rts51x_try_to_exit_ss(struct rts51x_chip *chip) -{ - pr_debug("Exit from SS state\n"); - usb_autopm_disable(chip->usb->pusb_intf); -} - -int rts51x_suspend(struct usb_interface *iface, pm_message_t message) -{ - struct rts51x_chip *chip = usb_get_intfdata(iface); - - pr_debug("%s, message.event = 0x%x\n", __func__, message.event); - - /* Wait until no command is running */ - mutex_lock(&chip->usb->dev_mutex); - - chip->fake_card_ready = chip->card_ready; - rts51x_do_before_power_down(chip); - - if (message.event == PM_EVENT_AUTO_SUSPEND) { - pr_debug("Enter SS state"); - chip->resume_from_scsi = 0; - RTS51X_SET_STAT(chip, STAT_SS); - } else { - pr_debug("Enter SUSPEND state"); - RTS51X_SET_STAT(chip, STAT_SUSPEND); - } - - /* When runtime PM is working, we'll set a flag to indicate - * whether we should autoresume when a SCSI request arrives. */ - - mutex_unlock(&chip->usb->dev_mutex); - return 0; -} - -int rts51x_resume(struct usb_interface *iface) -{ - struct rts51x_chip *chip = usb_get_intfdata(iface); - - pr_debug("%s\n", __func__); - - if (!RTS51X_CHK_STAT(chip, STAT_SS) || !chip->resume_from_scsi) { - mutex_lock(&chip->usb->dev_mutex); - - if (chip->option.ss_en) { - if (GET_PM_USAGE_CNT(chip) <= 0) { - /* Remote wake up, increase pm_usage_cnt */ - pr_debug("Incr pm_usage_cnt\n"); - SET_PM_USAGE_CNT(chip, 1); - } - } - - RTS51X_SET_STAT(chip, STAT_RUN); - - rts51x_init_chip(chip); - rts51x_init_cards(chip); - - mutex_unlock(&chip->usb->dev_mutex); - } - - return 0; -} - -int rts51x_reset_resume(struct usb_interface *iface) -{ - struct rts51x_chip *chip = usb_get_intfdata(iface); - - pr_debug("%s\n", __func__); - - mutex_lock(&chip->usb->dev_mutex); - - RTS51X_SET_STAT(chip, STAT_RUN); - - if (chip->option.ss_en) - SET_PM_USAGE_CNT(chip, 1); - - rts51x_init_chip(chip); - rts51x_init_cards(chip); - - mutex_unlock(&chip->usb->dev_mutex); - - /* FIXME: Notify the subdrivers that they need to reinitialize - * the device */ - return 0; -} - -#else /* CONFIG_PM */ - -static void rts51x_try_to_enter_ss(struct rts51x_chip *chip) -{ -} - -void rts51x_try_to_exit_ss(struct rts51x_chip *chip) -{ -} - -#endif /* CONFIG_PM */ - -/* - * The next two routines get called just before and just after - * a USB port reset, whether from this driver or a different one. - */ - -static int rts51x_pre_reset(struct usb_interface *iface) -{ - struct rts51x_chip *chip = usb_get_intfdata(iface); - - pr_debug("%s\n", __func__); - - /* Make sure no command runs during the reset */ - mutex_lock(&chip->usb->dev_mutex); - return 0; -} - -static int rts51x_post_reset(struct usb_interface *iface) -{ - struct rts51x_chip *chip = usb_get_intfdata(iface); - - pr_debug("%s\n", __func__); - - /* Report the reset to the SCSI core */ - /* usb_stor_report_bus_reset(us); */ - - /* FIXME: Notify the subdrivers that they need to reinitialize - * the device */ - - mutex_unlock(&chip->usb->dev_mutex); - return 0; -} - -static int rts51x_control_thread(void *__chip) -{ - struct rts51x_chip *chip = (struct rts51x_chip *)__chip; - struct Scsi_Host *host = rts51x_to_host(chip); - - for (;;) { - if (wait_for_completion_interruptible(&chip->usb->cmnd_ready)) - break; - - if (test_bit(FLIDX_DISCONNECTING, &chip->usb->dflags)) { - pr_debug("-- exiting from rts51x-control\n"); - break; - } - - /* lock the device pointers */ - mutex_lock(&(chip->usb->dev_mutex)); - - /* lock access to the state */ - scsi_lock(host); - - /* When we are called with no command pending, we're done */ - if (chip->srb == NULL) { - scsi_unlock(host); - mutex_unlock(&chip->usb->dev_mutex); - pr_debug("-- exiting from control thread\n"); - break; - } - - /* has the command timed out *already* ? */ - if (test_bit(FLIDX_TIMED_OUT, &chip->usb->dflags)) { - chip->srb->result = DID_ABORT << 16; - goto abort; - } - - scsi_unlock(host); - - /* reject the command if the direction indicator - * is UNKNOWN - */ - if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { - pr_debug("UNKNOWN data direction\n"); - chip->srb->result = DID_ERROR << 16; - } - - /* reject if target != 0 or if LUN is higher than - * the maximum known LUN - */ - else if (chip->srb->device->id) { - pr_debug("Bad target number (%d:%d)\n", - chip->srb->device->id, - chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } - - else if (chip->srb->device->lun > chip->max_lun) { - pr_debug("Bad LUN (%d:%d)\n", - chip->srb->device->id, - chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } - - /* we've got a command, let's do it! */ - else { - RTS51X_DEBUG(rts51x_scsi_show_command(chip->srb)); - rts51x_invoke_transport(chip->srb, chip); - } - - /* lock access to the state */ - scsi_lock(host); - - /* indicate that the command is done */ - if (chip->srb->result != DID_ABORT << 16) - chip->srb->scsi_done(chip->srb); - else -abort : - pr_debug("scsi command aborted\n"); - - /* If an abort request was received we need to signal that - * the abort has finished. The proper test for this is - * the TIMED_OUT flag, not srb->result == DID_ABORT, because - * the timeout might have occurred after the command had - * already completed with a different result code. */ - if (test_bit(FLIDX_TIMED_OUT, &chip->usb->dflags)) { - complete(&(chip->usb->notify)); - - /* Allow USB transfers to resume */ - clear_bit(FLIDX_ABORTING, &chip->usb->dflags); - clear_bit(FLIDX_TIMED_OUT, &chip->usb->dflags); - } - - /* finished working on this command */ - chip->srb = NULL; - scsi_unlock(host); - - /* unlock the device pointers */ - mutex_unlock(&chip->usb->dev_mutex); - } /* for (;;) */ - - complete(&chip->usb->control_exit); - - /* Wait until we are told to stop */ -/* for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) - break; - schedule(); - } - __set_current_state(TASK_RUNNING);*/ - return 0; -} - -static int rts51x_polling_thread(void *__chip) -{ - struct rts51x_chip *chip = (struct rts51x_chip *)__chip; - - for (;;) { - wait_timeout(POLLING_INTERVAL); - - /* if the device has disconnected, we are free to exit */ - if (test_bit(FLIDX_DISCONNECTING, &chip->usb->dflags)) { - pr_debug("-- exiting from rts51x-polling\n"); - break; - } - - /* if the device has disconnected, we are free to exit */ - /* if (kthread_should_stop()) { - printk(KERN_INFO "Stop polling thread!\n"); - break; - } */ - -#ifdef CONFIG_PM - if (RTS51X_CHK_STAT(chip, STAT_SS) || - RTS51X_CHK_STAT(chip, STAT_SS_PRE) || - RTS51X_CHK_STAT(chip, STAT_SUSPEND)) { - continue; - } - - if (ss_en) { - if (RTS51X_CHK_STAT(chip, STAT_IDLE)) { - if (chip->ss_counter < - (ss_delay * 1000 / POLLING_INTERVAL)) { - chip->ss_counter++; - } else { - /* Prepare SS state */ - RTS51X_SET_STAT(chip, STAT_SS_PRE); - rts51x_try_to_enter_ss(chip); - continue; - } - } else { - chip->ss_counter = 0; - } - } -#endif - - rts51x_mspro_polling_format_status(chip); - - /* lock the device pointers */ - mutex_lock(&(chip->usb->dev_mutex)); - - rts51x_polling_func(chip); - - /* unlock the device pointers */ - mutex_unlock(&chip->usb->dev_mutex); - } /* for (;;) */ - - complete(&chip->usb->polling_exit); - - /* Wait until we are told to stop */ - /* for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) - break; - schedule(); - } - __set_current_state(TASK_RUNNING); */ - return 0; -} - -/* Associate our private data with the USB device */ -static int associate_dev(struct rts51x_chip *chip, struct usb_interface *intf) -{ - struct rts51x_usb *rts51x = chip->usb; -#ifdef SUPPORT_FILE_OP - int retval; -#endif - - /* Fill in the device-related fields */ - rts51x->pusb_dev = interface_to_usbdev(intf); - rts51x->pusb_intf = intf; - rts51x->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; - pr_debug("Vendor: 0x%04x, Product: 0x%04x, Revision: 0x%04x\n", - le16_to_cpu(rts51x->pusb_dev->descriptor.idVendor), - le16_to_cpu(rts51x->pusb_dev->descriptor.idProduct), - le16_to_cpu(rts51x->pusb_dev->descriptor.bcdDevice)); - pr_debug("Interface Subclass: 0x%02x, Protocol: 0x%02x\n", - intf->cur_altsetting->desc.bInterfaceSubClass, - intf->cur_altsetting->desc.bInterfaceProtocol); - - /* Store our private data in the interface */ - usb_set_intfdata(intf, chip); - -#ifdef SUPPORT_FILE_OP - /* we can register the device now, as it is ready */ - retval = usb_register_dev(intf, &rts51x_class); - if (retval) { - /* something prevented us from registering this driver */ - pr_debug("Not able to get a minor for this device."); - usb_set_intfdata(intf, NULL); - return -ENOMEM; - } -#endif - - /* Allocate the device-related DMA-mapped buffers */ - rts51x->cr = usb_buffer_alloc(rts51x->pusb_dev, sizeof(*rts51x->cr), - GFP_KERNEL, &rts51x->cr_dma); - if (!rts51x->cr) { - usb_set_intfdata(intf, NULL); - return -ENOMEM; - } - - rts51x->iobuf = usb_buffer_alloc(rts51x->pusb_dev, RTS51X_IOBUF_SIZE, - GFP_KERNEL, &rts51x->iobuf_dma); - if (!rts51x->iobuf) { - usb_set_intfdata(intf, NULL); - return -ENOMEM; - } - return 0; -} - -static void rts51x_init_options(struct rts51x_chip *chip) -{ - struct rts51x_option *option = &(chip->option); - - option->rts51x_mspro_formatter_enable = 1; - - option->fpga_sd_sdr104_clk = CLK_100; - option->fpga_sd_sdr50_clk = CLK_100; - option->fpga_sd_ddr50_clk = CLK_100; - option->fpga_sd_hs_clk = CLK_100; - option->fpga_mmc_52m_clk = CLK_80; - option->fpga_ms_hg_clk = CLK_80; - option->fpga_ms_4bit_clk = CLK_80; - - option->asic_sd_sdr104_clk = 98; - option->asic_sd_sdr50_clk = 98; - option->asic_sd_ddr50_clk = 98; - option->asic_sd_hs_clk = 97; - option->asic_mmc_52m_clk = 95; - option->asic_ms_hg_clk = 116; - option->asic_ms_4bit_clk = 77; - - option->sd_ddr_tx_phase = 0; - option->mmc_ddr_tx_phase = 1; - - option->sd_speed_prior = 0; - option->sd_ctl = - SD_PUSH_POINT_AUTO | SD_SAMPLE_POINT_AUTO | SUPPORT_UHS50_MMC44; - - option->ss_en = ss_en; - option->ss_delay = ss_delay; - - option->auto_delink_en = auto_delink_en; - - option->FT2_fast_mode = 0; - option->pwr_delay = 800; - option->rts51x_xd_rw_step = 0; - option->D3318_off_delay = 50; - option->delink_delay = 100; - option->rts5129_D3318_off_enable = 0; - option->sd20_pad_drive = 0; - option->reset_or_rw_fail_set_pad_drive = 1; - option->debounce_num = 2; - option->led_toggle_interval = 6; - option->rts51x_xd_rwn_step = 0; - option->sd_send_status_en = 0; - option->sdr50_tx_phase = 0x01; - option->sdr50_rx_phase = 0x05; - option->ddr50_tx_phase = 0x09; - option->ddr50_rx_phase = 0x06; - option->sdr50_phase_sel = 0; - option->sd30_pad_drive = 1; - option->ms_errreg_fix = 0; - option->reset_mmc_first = 0; - option->speed_mmc = 1; - option->led_always_on = 0; -} - -/* Get the pipe settings */ -static int get_pipes(struct rts51x_chip *chip) -{ - struct rts51x_usb *rts51x = chip->usb; - struct usb_host_interface *altsetting = - rts51x->pusb_intf->cur_altsetting; - int i; - struct usb_endpoint_descriptor *ep; - struct usb_endpoint_descriptor *ep_in = NULL; - struct usb_endpoint_descriptor *ep_out = NULL; - struct usb_endpoint_descriptor *ep_int = NULL; - - /* - * Find the first endpoint of each type we need. - * We are expecting a minimum of 2 endpoints - in and out (bulk). - * An optional interrupt-in is OK (necessary for CBI protocol). - * We will ignore any others. - */ - for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { - ep = &altsetting->endpoint[i].desc; - - if (usb_endpoint_xfer_bulk(ep)) { - if (usb_endpoint_dir_in(ep)) { - if (!ep_in) - ep_in = ep; - } else { - if (!ep_out) - ep_out = ep; - } - } - - else if (usb_endpoint_is_int_in(ep)) { - if (!ep_int) - ep_int = ep; - } - } - - if (!ep_in || !ep_out) { - pr_debug("Endpoint sanity check failed! Rejecting dev.\n"); - return -EIO; - } - - /* Calculate and store the pipe values */ - rts51x->send_ctrl_pipe = usb_sndctrlpipe(rts51x->pusb_dev, 0); - rts51x->recv_ctrl_pipe = usb_rcvctrlpipe(rts51x->pusb_dev, 0); - rts51x->send_bulk_pipe = usb_sndbulkpipe(rts51x->pusb_dev, - usb_endpoint_num(ep_out)); - rts51x->recv_bulk_pipe = usb_rcvbulkpipe(rts51x->pusb_dev, - usb_endpoint_num(ep_in)); - if (ep_int) { - rts51x->recv_intr_pipe = usb_rcvintpipe(rts51x->pusb_dev, - usb_endpoint_num - (ep_int)); - rts51x->ep_bInterval = ep_int->bInterval; - } - return 0; -} - -/* Initialize all the dynamic resources we need */ -static int rts51x_acquire_resources(struct rts51x_chip *chip) -{ - struct rts51x_usb *rts51x = chip->usb; - int retval; - - rts51x->current_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rts51x->current_urb) - return -ENOMEM; - - rts51x->intr_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rts51x->intr_urb) - return -ENOMEM; - - chip->cmd_buf = rts51x->iobuf; - chip->rsp_buf = rts51x->iobuf; - - rts51x_init_options(chip); - - /* Init rts51xx device */ - retval = rts51x_init_chip(chip); - if (retval != STATUS_SUCCESS) - return -EIO; - - return 0; -} - -/* Release all our dynamic resources */ -static void rts51x_release_resources(struct rts51x_chip *chip) -{ - pr_debug("-- %s\n", __func__); - - /* Tell the control thread to exit. The SCSI host must - * already have been removed and the DISCONNECTING flag set - * so that we won't accept any more commands. - */ - pr_debug("-- sending exit command to thread\n"); - complete(&chip->usb->cmnd_ready); - if (chip->usb->ctl_thread) - wait_for_completion(&chip->usb->control_exit); - /* kthread_stop(chip->usb->ctl_thread); */ - if (chip->usb->polling_thread) - wait_for_completion(&chip->usb->polling_exit); - - /* if (chip->usb->polling_thread) - kthread_stop(chip->usb->polling_thread); */ - - wait_timeout(200); - - /* Release rts51xx device here */ - rts51x_release_chip(chip); - - usb_free_urb(chip->usb->current_urb); - usb_free_urb(chip->usb->intr_urb); -} - -/* Dissociate from the USB device */ -static void dissociate_dev(struct rts51x_chip *chip) -{ - struct rts51x_usb *rts51x = chip->usb; - - pr_debug("-- %s\n", __func__); - - /* Free the device-related DMA-mapped buffers */ - if (rts51x->cr) - usb_buffer_free(rts51x->pusb_dev, sizeof(*rts51x->cr), - rts51x->cr, rts51x->cr_dma); - if (rts51x->iobuf) - usb_buffer_free(rts51x->pusb_dev, RTS51X_IOBUF_SIZE, - rts51x->iobuf, rts51x->iobuf_dma); - - /* Remove our private data from the interface */ - usb_set_intfdata(rts51x->pusb_intf, NULL); - -#ifdef SUPPORT_FILE_OP - /* give back our minor */ - usb_deregister_dev(rts51x->pusb_intf, &rts51x_class); -#endif - - kfree(rts51x); - chip->usb = NULL; -} - -/* First stage of disconnect processing: stop SCSI scanning, - * remove the host, and stop accepting new commands - */ -static void quiesce_and_remove_host(struct rts51x_chip *chip) -{ - struct rts51x_usb *rts51x = chip->usb; - struct Scsi_Host *host = rts51x_to_host(chip); - - /* If the device is really gone, cut short reset delays */ - if (rts51x->pusb_dev->state == USB_STATE_NOTATTACHED) - set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); - - /* Removing the host will perform an orderly shutdown: caches - * synchronized, disks spun down, etc. - */ - scsi_remove_host(host); - - /* Prevent any new commands from being accepted and cut short - * reset delays. - */ - scsi_lock(host); - set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); - scsi_unlock(host); -} - -/* Second stage of disconnect processing: deallocate all resources */ -static void release_everything(struct rts51x_chip *chip) -{ - rts51x_release_resources(chip); - dissociate_dev(chip); - - /* Drop our reference to the host; the SCSI core will free it - * (and "chip" along with it) when the refcount becomes 0. */ - scsi_host_put(rts51x_to_host(chip)); -} - -static int rts51x_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct Scsi_Host *host; - struct rts51x_chip *chip; - struct rts51x_usb *rts51x; - int result; - struct task_struct *th; - - pr_debug("%s detected\n", RTS51X_NAME); - - rts51x = kzalloc(sizeof(*rts51x), GFP_KERNEL); - if (!rts51x) - return -ENOMEM; - - /* - * Ask the SCSI layer to allocate a host structure, with extra - * space at the end for our private us_data structure. - */ - host = scsi_host_alloc(&rts51x_host_template, sizeof(*chip)); - if (!host) { - kfree(rts51x); - return -ENOMEM; - } - - /* - * Allow 16-byte CDBs and thus > 2TB - */ - host->max_cmd_len = 16; - chip = host_to_rts51x(host); - memset(chip, 0, sizeof(struct rts51x_chip)); - - chip->vendor_id = id->idVendor; - chip->product_id = id->idProduct; - - mutex_init(&(rts51x->dev_mutex)); - init_completion(&rts51x->cmnd_ready); - init_completion(&rts51x->control_exit); - init_completion(&rts51x->polling_exit); - init_completion(&(rts51x->notify)); - - chip->usb = rts51x; - - /* Associate the us_data structure with the USB device */ - result = associate_dev(chip, intf); - if (result) - goto bad_device; - - /* Find the endpoints and calculate pipe values */ - result = get_pipes(chip); - if (result) - goto bad_device; - - /* Acquire all the other resources and add the host */ - result = rts51x_acquire_resources(chip); - if (result) - goto bad_device; - - /* Start up our control thread */ - th = kthread_run(rts51x_control_thread, chip, RTS51X_CTL_THREAD); - if (IS_ERR(th)) { - pr_warn("Unable to start control thread\n"); - result = PTR_ERR(th); - goto bad_device; - } - rts51x->ctl_thread = th; - - result = scsi_add_host(rts51x_to_host(chip), &rts51x->pusb_intf->dev); - if (result) { - pr_warn("Unable to add the scsi host\n"); - goto bad_device; - } - scsi_scan_host(rts51x_to_host(chip)); - - /* Start up our polling thread */ - th = kthread_run(rts51x_polling_thread, chip, RTS51X_POLLING_THREAD); - if (IS_ERR(th)) { - pr_warn("Unable to start polling thread\n"); - result = PTR_ERR(th); - goto bad_device; - } - rts51x->polling_thread = th; - -#ifdef CONFIG_PM - if (ss_en) { - rts51x->pusb_intf->needs_remote_wakeup = needs_remote_wakeup; - SET_PM_USAGE_CNT(chip, 1); - pr_debug("pm_usage_cnt = %d\n", GET_PM_USAGE_CNT(chip)); - } -#endif - - return 0; - - /* We come here if there are any problems */ -bad_device: - pr_debug("rts51x_probe() failed\n"); - release_everything(chip); - return result; -} - -static void rts51x_disconnect(struct usb_interface *intf) -{ - struct rts51x_chip *chip = (struct rts51x_chip *)usb_get_intfdata(intf); - - pr_debug("rts51x_disconnect() called\n"); - quiesce_and_remove_host(chip); - release_everything(chip); -} - -/*********************************************************************** - * Initialization and registration - ***********************************************************************/ - -static struct usb_device_id rts5139_usb_ids[] = { - {USB_DEVICE(0x0BDA, 0x0139)}, - {USB_DEVICE(0x0BDA, 0x0129)}, - {} /* Terminating entry */ -}; -EXPORT_SYMBOL_GPL(rts5139_usb_ids); - -MODULE_DEVICE_TABLE(usb, rts5139_usb_ids); - -struct usb_driver rts51x_driver = { - .name = RTS51X_NAME, - .probe = rts51x_probe, - .disconnect = rts51x_disconnect, - .suspend = rts51x_suspend, - .resume = rts51x_resume, - .reset_resume = rts51x_reset_resume, - .pre_reset = rts51x_pre_reset, - .post_reset = rts51x_post_reset, - .id_table = rts5139_usb_ids, - .soft_unbind = 1, -}; - -module_usb_driver(rts51x_driver); diff --git a/drivers/staging/rts5139/rts51x.h b/drivers/staging/rts5139/rts51x.h deleted file mode 100644 index ecc0109a5b1a..000000000000 --- a/drivers/staging/rts5139/rts51x.h +++ /dev/null @@ -1,194 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_H -#define __RTS51X_H - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define DRIVER_VERSION "v1.04" - -#define RTS51X_DESC "Realtek RTS5139/29 USB card reader driver" -#define RTS51X_NAME "rts5139" -#define RTS51X_CTL_THREAD "rts5139-control" -#define RTS51X_POLLING_THREAD "rts5139-polling" - -#define POLLING_IN_THREAD -#define SUPPORT_FILE_OP - -#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 SCSI_LUN(srb) ((srb)->device->lun) - -/* Size of the DMA-mapped I/O buffer */ -#define RTS51X_IOBUF_SIZE 1024 - -/* Dynamic bitflag definitions (dflags): used in set_bit() etc. */ -#define FLIDX_URB_ACTIVE 0 /* current_urb is in use */ -#define FLIDX_SG_ACTIVE 1 /* current_sg is in use */ -#define FLIDX_ABORTING 2 /* abort is in progress */ -#define FLIDX_DISCONNECTING 3 /* disconnect in progress */ -#define FLIDX_RESETTING 4 /* device reset in progress */ -#define FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ - -struct rts51x_chip; - -struct rts51x_usb { - /* The device we're working with - * It's important to note: - * (o) you must hold dev_mutex to change pusb_dev - */ - struct mutex dev_mutex; /* protect pusb_dev */ - struct usb_device *pusb_dev; /* this usb_device */ - struct usb_interface *pusb_intf; /* this interface */ - - unsigned long dflags; /* dynamic atomic bitflags */ - - unsigned int send_bulk_pipe; /* cached pipe values */ - unsigned int recv_bulk_pipe; - unsigned int send_ctrl_pipe; - unsigned int recv_ctrl_pipe; - unsigned int recv_intr_pipe; - - u8 ifnum; /* interface number */ - u8 ep_bInterval; /* interrupt interval */ - - /* control and bulk communications data */ - struct urb *current_urb; /* USB requests */ - struct urb *intr_urb; /* Interrupt USB request */ - struct usb_ctrlrequest *cr; /* control requests */ - struct usb_sg_request current_sg; /* scatter-gather req. */ - unsigned char *iobuf; /* I/O buffer */ - dma_addr_t cr_dma; /* buffer DMA addresses */ - dma_addr_t iobuf_dma; - 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 */ -}; - -extern struct usb_driver rts51x_driver; - -static inline void get_current_time(u8 *timeval_buf, int buf_len) -{ - struct timeval tv; - - if (!timeval_buf || (buf_len < 8)) - return; - - do_gettimeofday(&tv); - - timeval_buf[0] = (u8) (tv.tv_sec >> 24); - timeval_buf[1] = (u8) (tv.tv_sec >> 16); - timeval_buf[2] = (u8) (tv.tv_sec >> 8); - timeval_buf[3] = (u8) (tv.tv_sec); - timeval_buf[4] = (u8) (tv.tv_usec >> 24); - timeval_buf[5] = (u8) (tv.tv_usec >> 16); - timeval_buf[6] = (u8) (tv.tv_usec >> 8); - timeval_buf[7] = (u8) (tv.tv_usec); -} - -#define SND_CTRL_PIPE(chip) ((chip)->usb->send_ctrl_pipe) -#define RCV_CTRL_PIPE(chip) ((chip)->usb->recv_ctrl_pipe) -#define SND_BULK_PIPE(chip) ((chip)->usb->send_bulk_pipe) -#define RCV_BULK_PIPE(chip) ((chip)->usb->recv_bulk_pipe) -#define RCV_INTR_PIPE(chip) ((chip)->usb->recv_intr_pipe) - -/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the - * single queue element srb for write access */ -#define scsi_unlock(host) spin_unlock_irq(host->host_lock) -#define scsi_lock(host) spin_lock_irq(host->host_lock) - -#define GET_PM_USAGE_CNT(chip) \ - atomic_read(&((chip)->usb->pusb_intf->pm_usage_cnt)) -#define SET_PM_USAGE_CNT(chip, cnt) \ - atomic_set(&((chip)->usb->pusb_intf->pm_usage_cnt), (cnt)) - -/* Compatible macros while we switch over */ -static inline void *usb_buffer_alloc(struct usb_device *dev, size_t size, - gfp_t mem_flags, dma_addr_t *dma) -{ - return usb_alloc_coherent(dev, size, mem_flags, dma); -} - -static inline void usb_buffer_free(struct usb_device *dev, size_t size, - void *addr, dma_addr_t dma) -{ - return usb_free_coherent(dev, size, addr, dma); -} - -/* Convert between us_data and the corresponding Scsi_Host */ -static inline struct Scsi_Host *rts51x_to_host(struct rts51x_chip *chip) -{ - return container_of((void *)chip, struct Scsi_Host, hostdata); -} - -static inline struct rts51x_chip *host_to_rts51x(struct Scsi_Host *host) -{ - return (struct rts51x_chip *)(host->hostdata); -} - -/* struct scsi_cmnd transfer buffer access utilities */ -enum xfer_buf_dir { TO_XFER_BUF, FROM_XFER_BUF }; - -/* General routines provided by the usb-storage standard core */ -#ifdef CONFIG_PM -void rts51x_try_to_exit_ss(struct rts51x_chip *chip); -int rts51x_suspend(struct usb_interface *iface, pm_message_t message); -int rts51x_resume(struct usb_interface *iface); -int rts51x_reset_resume(struct usb_interface *iface); -#else -#define rts51x_suspend NULL -#define rts51x_resume NULL -#define rts51x_reset_resume NULL -#endif - -extern struct scsi_host_template rts51x_host_template; - -#endif /* __RTS51X_H */ diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c deleted file mode 100644 index 03456d9873e5..000000000000 --- a/drivers/staging/rts5139/rts51x_card.c +++ /dev/null @@ -1,940 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "debug.h" -#include "rts51x.h" -#include "rts51x_chip.h" -#include "rts51x_card.h" -#include "rts51x_transport.h" -#include "xd.h" -#include "sd.h" -#include "ms.h" - -void rts51x_do_remaining_work(struct rts51x_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); - - if (chip->card_ready & SD_CARD) { - if (sd_card->seq_mode) { - RTS51X_SET_STAT(chip, STAT_RUN); - sd_card->counter++; - } else { - sd_card->counter = 0; - } - } - - if (chip->card_ready & XD_CARD) { - if (xd_card->delay_write.delay_write_flag) { - RTS51X_SET_STAT(chip, STAT_RUN); - xd_card->counter++; - } else { - xd_card->counter = 0; - } - } - - if (chip->card_ready & MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - RTS51X_SET_STAT(chip, STAT_RUN); - ms_card->counter++; - } else { - ms_card->counter = 0; - } - } else { - if (ms_card->delay_write.delay_write_flag) { - RTS51X_SET_STAT(chip, STAT_RUN); - ms_card->counter++; - } else { - ms_card->counter = 0; - } - } - } - - if (sd_card->counter > POLLING_WAIT_CNT) - rts51x_sd_cleanup_work(chip); - - if (xd_card->counter > POLLING_WAIT_CNT) - rts51x_xd_cleanup_work(chip); - - if (ms_card->counter > POLLING_WAIT_CNT) - rts51x_ms_cleanup_work(chip); -} - -static void do_rts51x_reset_xd_card(struct rts51x_chip *chip) -{ - int retval; - - if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) - return; - - retval = rts51x_reset_xd_card(chip); - if (retval == STATUS_SUCCESS) { - chip->card_ready |= XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->rw_card[chip->card2lun[XD_CARD]] = rts51x_xd_rw; - } else { - 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; - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, XD_CLK_EN, 0); - rts51x_send_cmd(chip, MODE_C, 100); - } -} - -void rts51x_do_rts51x_reset_sd_card(struct rts51x_chip *chip) -{ - int retval; - - if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) - return; - - retval = rts51x_reset_sd_card(chip); - if (retval == STATUS_SUCCESS) { - chip->card_ready |= SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->rw_card[chip->card2lun[SD_CARD]] = rts51x_sd_rw; - } else { - 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; - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0); - rts51x_send_cmd(chip, MODE_C, 100); - } -} - -static void do_rts51x_reset_ms_card(struct rts51x_chip *chip) -{ - int retval; - - if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) - return; - - retval = rts51x_reset_ms_card(chip); - if (retval == STATUS_SUCCESS) { - chip->card_ready |= MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->rw_card[chip->card2lun[MS_CARD]] = rts51x_ms_rw; - } else { - 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; - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0); - rts51x_send_cmd(chip, MODE_C, 100); - } -} - -static void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, - u8 *need_release) -{ - int retval; - u8 release_map = 0, reset_map = 0; - u8 value; - - retval = rts51x_get_card_status(chip, &(chip->card_status)); -#ifdef SUPPORT_OCP - chip->ocp_stat = (chip->card_status >> 4) & 0x03; -#endif - - if (retval != STATUS_SUCCESS) - goto Exit_Debounce; - - if (chip->card_exist) { - retval = rts51x_read_register(chip, CARD_INT_PEND, &value); - if (retval != STATUS_SUCCESS) { - rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, - FIFO_FLUSH); - rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); - value = 0; - } - - if (chip->card_exist & XD_CARD) { - if (!(chip->card_status & XD_CD)) - release_map |= XD_CARD; - } else if (chip->card_exist & SD_CARD) { - /* if (!(chip->card_status & SD_CD)) { */ - if (!(chip->card_status & SD_CD) || (value & SD_INT)) - release_map |= SD_CARD; - } else if (chip->card_exist & MS_CARD) { - /* if (!(chip->card_status & MS_CD)) { */ - if (!(chip->card_status & MS_CD) || (value & MS_INT)) - release_map |= MS_CARD; - } - } else { - if (chip->card_status & XD_CD) - reset_map |= XD_CARD; - else if (chip->card_status & SD_CD) - reset_map |= SD_CARD; - else if (chip->card_status & MS_CD) - reset_map |= MS_CARD; - } - - if (CHECK_PKG(chip, QFN24) && reset_map) { - if (chip->card_exist & XD_CARD) { - reset_map = 0; - goto Exit_Debounce; - } - } - - if (reset_map) { - int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; - int i; - - for (i = 0; i < (chip->option.debounce_num); i++) { - retval = - rts51x_get_card_status(chip, &(chip->card_status)); - if (retval != STATUS_SUCCESS) { - reset_map = release_map = 0; - goto Exit_Debounce; - } - if (chip->card_status & XD_CD) - xd_cnt++; - else - xd_cnt = 0; - if (chip->card_status & SD_CD) - sd_cnt++; - else - sd_cnt = 0; - if (chip->card_status & MS_CD) - ms_cnt++; - else - ms_cnt = 0; - wait_timeout(30); - } - - reset_map = 0; - if (!(chip->card_exist & XD_CARD) - && (xd_cnt > (chip->option.debounce_num - 1))) { - reset_map |= XD_CARD; - } - if (!(chip->card_exist & SD_CARD) - && (sd_cnt > (chip->option.debounce_num - 1))) { - reset_map |= SD_CARD; - } - if (!(chip->card_exist & MS_CARD) - && (ms_cnt > (chip->option.debounce_num - 1))) { - reset_map |= MS_CARD; - } - } - rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT, - XD_INT | MS_INT | SD_INT); - -Exit_Debounce: - if (need_reset) - *need_reset = reset_map; - if (need_release) - *need_release = release_map; -} - -void rts51x_init_cards(struct rts51x_chip *chip) -{ - u8 need_reset = 0, need_release = 0; - - card_cd_debounce(chip, &need_reset, &need_release); - - if (need_release) { - RTS51X_DEBUGP("need_release = 0x%x\n", need_release); - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - -#ifdef SUPPORT_OCP - if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { - rts51x_write_register(chip, OCPCTL, MS_OCP_CLEAR, - MS_OCP_CLEAR); - chip->ocp_stat = 0; - RTS51X_DEBUGP("Clear OCP status.\n"); - } -#endif - - if (need_release & XD_CARD) { - chip->card_exist &= ~XD_CARD; - chip->card_ejected = 0; - if (chip->card_ready & XD_CARD) { - rts51x_release_xd_card(chip); - chip->rw_card[chip->card2lun[XD_CARD]] = NULL; - clear_bit(chip->card2lun[XD_CARD], - &(chip->lun_mc)); - } - } - - if (need_release & SD_CARD) { - chip->card_exist &= ~SD_CARD; - chip->card_ejected = 0; - if (chip->card_ready & SD_CARD) { - rts51x_release_sd_card(chip); - chip->rw_card[chip->card2lun[SD_CARD]] = NULL; - clear_bit(chip->card2lun[SD_CARD], - &(chip->lun_mc)); - } - } - - if (need_release & MS_CARD) { - chip->card_exist &= ~MS_CARD; - chip->card_ejected = 0; - if (chip->card_ready & MS_CARD) { - rts51x_release_ms_card(chip); - chip->rw_card[chip->card2lun[MS_CARD]] = NULL; - clear_bit(chip->card2lun[MS_CARD], - &(chip->lun_mc)); - } - } - } - - if (need_reset && !chip->card_ready) { - RTS51X_DEBUGP("need_reset = 0x%x\n", need_reset); - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - if (need_reset & XD_CARD) { - chip->card_exist |= XD_CARD; - do_rts51x_reset_xd_card(chip); - } else if (need_reset & SD_CARD) { - chip->card_exist |= SD_CARD; - rts51x_do_rts51x_reset_sd_card(chip); - } else if (need_reset & MS_CARD) { - chip->card_exist |= MS_CARD; - do_rts51x_reset_ms_card(chip); - } - } -} - -void rts51x_release_cards(struct rts51x_chip *chip) -{ - if (chip->card_ready & SD_CARD) { - rts51x_sd_cleanup_work(chip); - rts51x_release_sd_card(chip); - chip->card_ready &= ~SD_CARD; - } - - if (chip->card_ready & XD_CARD) { - rts51x_xd_cleanup_work(chip); - rts51x_release_xd_card(chip); - chip->card_ready &= ~XD_CARD; - } - - if (chip->card_ready & MS_CARD) { - rts51x_ms_cleanup_work(chip); - rts51x_release_ms_card(chip); - chip->card_ready &= ~MS_CARD; - } -} - -static inline u8 double_depth(u8 depth) -{ - return (depth > 1) ? (depth - 1) : depth; -} - -int rts51x_switch_ssc_clock(struct rts51x_chip *chip, int clk) -{ - struct sd_info *sd_card = &(chip->sd_card); - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 N = (u8) (clk - 2), min_N, max_N; - u8 mcu_cnt, div, max_div, ssc_depth; - 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; - - RTS51X_DEBUGP("Switch SSC clock to %dMHz\n", clk); - - if ((clk <= 2) || (N > max_N)) - TRACE_RET(chip, STATUS_FAIL); - - mcu_cnt = (u8) (60 / clk + 3); - if (mcu_cnt > 15) - mcu_cnt = 15; - /* To make sure that the SSC clock div_n is - * equal or greater than min_N */ - div = CLK_DIV_1; - while ((N < min_N) && (div < max_div)) { - N = (N + 2) * 2 - 2; - div++; - } - RTS51X_DEBUGP("N = %d, div = %d\n", N, div); - - if (chip->option.ssc_en) { - if (chip->cur_card == SD_CARD) { - if (CHK_SD_SDR104(sd_card)) { - ssc_depth = chip->option.ssc_depth_sd_sdr104; - } else if (CHK_SD_SDR50(sd_card)) { - ssc_depth = chip->option.ssc_depth_sd_sdr50; - } else if (CHK_SD_DDR50(sd_card)) { - ssc_depth = - double_depth(chip->option. - ssc_depth_sd_ddr50); - } else if (CHK_SD_HS(sd_card)) { - ssc_depth = - double_depth(chip->option.ssc_depth_sd_hs); - } else if (CHK_MMC_52M(sd_card) - || CHK_MMC_DDR52(sd_card)) { - ssc_depth = - double_depth(chip->option. - ssc_depth_mmc_52m); - } else { - ssc_depth = - double_depth(chip->option. - ssc_depth_low_speed); - } - } else if (chip->cur_card == MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (CHK_HG8BIT(ms_card)) { - ssc_depth = - double_depth(chip->option. - ssc_depth_ms_hg); - } else { - ssc_depth = - double_depth(chip->option. - ssc_depth_ms_4bit); - } - } else { - if (CHK_MS4BIT(ms_card)) { - ssc_depth = - double_depth(chip->option. - ssc_depth_ms_4bit); - } else { - ssc_depth = - double_depth(chip->option. - ssc_depth_low_speed); - } - } - } else { - ssc_depth = - double_depth(chip->option.ssc_depth_low_speed); - } - - if (ssc_depth) { - if (div == CLK_DIV_2) { - /* If clock divided by 2, ssc depth must - * be multiplied by 2 */ - if (ssc_depth > 1) - ssc_depth -= 1; - else - ssc_depth = SSC_DEPTH_2M; - } else if (div == CLK_DIV_4) { - /* If clock divided by 4, ssc depth must - * be multiplied by 4 */ - if (ssc_depth > 2) - ssc_depth -= 2; - else - ssc_depth = SSC_DEPTH_2M; - } - } - } else { - /* Disable SSC */ - ssc_depth = 0; - } - - RTS51X_DEBUGP("ssc_depth = %d\n", ssc_depth); - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE); - rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F, - (div << 4) | mcu_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, SSC_DEPTH_MASK, - ssc_depth); - rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); - if (sd_vpclk_phase_reset) { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - } - - retval = rts51x_send_cmd(chip, MODE_C, 2000); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (chip->option.ssc_en && ssc_depth) - rts51x_write_register(chip, SSC_CTL1, 0xff, 0xD0); - else - rts51x_write_register(chip, SSC_CTL1, 0xff, 0x50); - udelay(100); - RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -int rts51x_switch_normal_clock(struct rts51x_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; - - if (chip->cur_card == SD_CARD) { - struct sd_info *sd_card = &(chip->sd_card); - if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) - sd_vpclk_phase_reset = 1; - } - - switch (clk) { - case CLK_20: - RTS51X_DEBUGP("Switch clock to 20MHz\n"); - sel = SSC_80; - div = CLK_DIV_4; - mcu_cnt = 5; - break; - - case CLK_30: - RTS51X_DEBUGP("Switch clock to 30MHz\n"); - sel = SSC_60; - div = CLK_DIV_2; - mcu_cnt = 4; - break; - - case CLK_40: - RTS51X_DEBUGP("Switch clock to 40MHz\n"); - sel = SSC_80; - div = CLK_DIV_2; - mcu_cnt = 3; - break; - - case CLK_50: - RTS51X_DEBUGP("Switch clock to 50MHz\n"); - sel = SSC_100; - div = CLK_DIV_2; - mcu_cnt = 3; - break; - - case CLK_60: - RTS51X_DEBUGP("Switch clock to 60MHz\n"); - sel = SSC_60; - div = CLK_DIV_1; - mcu_cnt = 3; - break; - - case CLK_80: - RTS51X_DEBUGP("Switch clock to 80MHz\n"); - sel = SSC_80; - div = CLK_DIV_1; - mcu_cnt = 2; - break; - - case CLK_100: - RTS51X_DEBUGP("Switch clock to 100MHz\n"); - sel = SSC_100; - div = CLK_DIV_1; - mcu_cnt = 2; - break; - - /* case CLK_120: - RTS51X_DEBUGP("Switch clock to 120MHz\n"); - sel = SSC_120; - div = CLK_DIV_1; - mcu_cnt = 2; - break; - - case CLK_150: - RTS51X_DEBUGP("Switch clock to 150MHz\n"); - sel = SSC_150; - div = CLK_DIV_1; - mcu_cnt = 2; - break; */ - - default: - RTS51X_DEBUGP("Try to switch to an illegal clock (%d)\n", - clk); - TRACE_RET(chip, STATUS_FAIL); - } - - if (!sd_vpclk_phase_reset) { - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, - CLK_CHANGE); - rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F, - (div << 4) | mcu_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CLK_FPGA_SEL, 0xFF, - sel); - rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, 0); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, - CLK_CHANGE); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK1_CTL, - PHASE_NOT_RESET, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F, - (div << 4) | mcu_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CLK_FPGA_SEL, 0xFF, - sel); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - udelay(200); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK1_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - udelay(200); - - RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); - } - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -int rts51x_card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, - u32 sec_addr, u16 sec_cnt) -{ - int retval; - unsigned int lun = SCSI_LUN(srb); - int i; - - if (chip->rw_card[lun] == NULL) - return STATUS_FAIL; - - RTS51X_DEBUGP("%s card, sector addr: 0x%x, sector cnt: %d\n", - (srb->sc_data_direction == - DMA_TO_DEVICE) ? "Write" : "Read", sec_addr, sec_cnt); - - chip->rw_need_retry = 0; - for (i = 0; i < 3; i++) { - retval = chip->rw_card[lun] (srb, chip, sec_addr, sec_cnt); - if (retval != STATUS_SUCCESS) { - CATCH_TRIGGER(chip); - if (chip->option.reset_or_rw_fail_set_pad_drive) { - rts51x_write_register(chip, CARD_DRIVE_SEL, - SD20_DRIVE_MASK, - DRIVE_8mA); - } - } - - if (!chip->rw_need_retry) - break; - - RTS51X_DEBUGP("Retry RW, (i = %d\n)", i); - } - - return retval; -} - -u8 rts51x_get_lun_card(struct rts51x_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; -} - -static int card_share_mode(struct rts51x_chip *chip, int card) -{ - u8 value; - - if (card == SD_CARD) - value = CARD_SHARE_SD; - else if (card == MS_CARD) - value = CARD_SHARE_MS; - else if (card == XD_CARD) - value = CARD_SHARE_XD; - else - TRACE_RET(chip, STATUS_FAIL); - - RTS51X_WRITE_REG(chip, CARD_SHARE_MODE, CARD_SHARE_MASK, value); - - return STATUS_SUCCESS; -} - -int rts51x_select_card(struct rts51x_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 - TRACE_RET(chip, STATUS_FAIL); - RTS51X_WRITE_REG(chip, CARD_SELECT, 0x07, mod); - chip->cur_card = card; - - retval = card_share_mode(chip, card); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -void rts51x_eject_card(struct rts51x_chip *chip, unsigned int lun) -{ - RTS51X_DEBUGP("eject card\n"); - RTS51X_SET_STAT(chip, STAT_RUN); - rts51x_do_remaining_work(chip); - - if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { - rts51x_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) { - rts51x_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) { - rts51x_release_ms_card(chip); - chip->card_ejected |= MS_CARD; - chip->card_ready &= ~MS_CARD; - chip->capacity[lun] = 0; - } - rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT, - XD_INT | MS_INT | SD_INT); -} - -void rts51x_trans_dma_enable(enum dma_data_direction dir, - struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size) -{ - if (pack_size > DMA_1024) - pack_size = DMA_512; - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - RING_BUFFER); - - rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC3, 0xFF, - (u8) (byte_cnt >> 24)); - rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC2, 0xFF, - (u8) (byte_cnt >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC1, 0xFF, - (u8) (byte_cnt >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC0, 0xFF, (u8) byte_cnt); - - if (dir == DMA_FROM_DEVICE) { - rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_CTL, - 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_FROM_CARD | DMA_EN | pack_size); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_CTL, - 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_TO_CARD | DMA_EN | pack_size); - } -} - -int rts51x_enable_card_clock(struct rts51x_chip *chip, u8 card) -{ - 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; - - RTS51X_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en); - - return STATUS_SUCCESS; -} - -int rts51x_card_power_on(struct rts51x_chip *chip, u8 card) -{ - u8 mask, val1, val2; - - mask = POWER_MASK; - val1 = PARTIAL_POWER_ON; - val2 = POWER_ON; - -#ifdef SD_XD_IO_FOLLOW_PWR - if ((card == SD_CARD) || (card == XD_CARD)) { - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask | LDO3318_PWR_MASK, - val1 | LDO_SUSPEND); - } else { -#endif - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val1); -#ifdef SD_XD_IO_FOLLOW_PWR - } -#endif - udelay(chip->option.pwr_delay); - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val2); -#ifdef SD_XD_IO_FOLLOW_PWR - if (card == SD_CARD) { - rts51x_write_register(chip, CARD_PWR_CTL, LDO3318_PWR_MASK, - LDO_ON); - } -#endif - - return STATUS_SUCCESS; -} - -int monitor_card_cd(struct rts51x_chip *chip, u8 card) -{ - int retval; - u8 card_cd[32] = { 0 }; - - card_cd[SD_CARD] = SD_CD; - card_cd[XD_CARD] = XD_CD; - card_cd[MS_CARD] = MS_CD; - - retval = rts51x_get_card_status(chip, &(chip->card_status)); - if (retval != STATUS_SUCCESS) - return CD_NOT_EXIST; - - if (chip->card_status & card_cd[card]) - return CD_EXIST; - - return CD_NOT_EXIST; -} - -int rts51x_toggle_gpio(struct rts51x_chip *chip, u8 gpio) -{ - int retval; - u8 temp_reg; - u8 gpio_output[4] = { - 0x01, - }; - u8 gpio_oe[4] = { - 0x02, - }; - if (chip->rts5179) { - retval = rts51x_ep0_read_register(chip, CARD_GPIO, &temp_reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - temp_reg ^= gpio_oe[gpio]; - temp_reg &= 0xfe; /* bit 0 always set 0 */ - retval = - rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, temp_reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - retval = rts51x_ep0_read_register(chip, CARD_GPIO, &temp_reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - temp_reg ^= gpio_output[gpio]; - retval = - rts51x_ep0_write_register(chip, CARD_GPIO, 0xFF, - temp_reg | gpio_oe[gpio]); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int rts51x_turn_on_led(struct rts51x_chip *chip, u8 gpio) -{ - int retval; - u8 gpio_oe[4] = { - 0x02, - }; - u8 gpio_mask[4] = { - 0x03, - }; - - retval = - rts51x_ep0_write_register(chip, CARD_GPIO, gpio_mask[gpio], - gpio_oe[gpio]); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int rts51x_turn_off_led(struct rts51x_chip *chip, u8 gpio) -{ - int retval; - u8 gpio_output[4] = { - 0x01, - }; - u8 gpio_oe[4] = { - 0x02, - }; - u8 gpio_mask[4] = { - 0x03, - }; - - retval = - rts51x_ep0_write_register(chip, CARD_GPIO, gpio_mask[gpio], - gpio_oe[gpio] | gpio_output[gpio]); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h deleted file mode 100644 index df8816e0f840..000000000000 --- a/drivers/staging/rts5139/rts51x_card.h +++ /dev/null @@ -1,870 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_CARD_H -#define __RTS51X_CARD_H - -#include "rts51x_chip.h" - -/* Register bit definition */ - -/* Card Power Control Register */ -#define POWER_OFF 0x03 -#define PARTIAL_POWER_ON 0x02 -#define POWER_ON 0x00 -#define POWER_MASK 0x03 -#define LDO3318_PWR_MASK 0x0C -#define LDO_ON 0x00 -#define LDO_SUSPEND 0x08 -#define LDO_OFF 0x0C -#define DV3318_AUTO_PWR_OFF 0x10 -#define FORCE_LDO_POWERB 0x60 - -/* Card Output Enable Register */ -#define XD_OUTPUT_EN 0x02 -#define SD_OUTPUT_EN 0x04 -#define MS_OUTPUT_EN 0x08 - -/* System Clock Control Register */ - -/* System Clock Divider Register */ -#define CLK_CHANGE 0x80 -#define CLK_DIV_1 0x00 -#define CLK_DIV_2 0x01 -#define CLK_DIV_4 0x02 -#define CLK_DIV_8 0x03 - -/* System Clock Select Register */ -#define SSC_60 0 -#define SSC_80 1 -#define SSC_100 2 -#define SSC_120 3 -#define SSC_150 4 - -/* Card Clock Enable Register */ -#define XD_CLK_EN 0x02 -#define SD_CLK_EN 0x04 -#define MS_CLK_EN 0x08 - -/* Card Select Register */ -#define XD_MOD_SEL 1 -#define SD_MOD_SEL 2 -#define MS_MOD_SEL 3 - -/* Card Transfer Reset Register */ -#define XD_STOP 0x02 -#define SD_STOP 0x04 -#define MS_STOP 0x08 -#define XD_CLR_ERR 0x20 -#define SD_CLR_ERR 0x40 -#define MS_CLR_ERR 0x80 - -/* SD30_drive_sel */ -#define SD30_DRIVE_MASK 0x07 - -/* CARD_DRIVE_SEL */ -#define SD20_DRIVE_MASK 0x03 -#define DRIVE_4mA 0x00 -#define DRIVE_8mA 0x01 -#define DRIVE_12mA 0x02 - -/* FPGA_PULL_CTL */ -#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 - -/* Card Data Source Register */ -#define PINGPONG_BUFFER 0x01 -#define RING_BUFFER 0x00 - -/* SFSM_ED */ -#define HW_CMD_STOP 0x80 -#define CLR_STAGE_STALL 0x08 -#define CARD_ERR 0x10 - -/* CARD_SHARE_MODE */ -#define CARD_SHARE_LQFP48 0x04 -#define CARD_SHARE_QFN24 0x00 -#define CARD_SHARE_LQFP_SEL 0x04 -#define CARD_SHARE_XD 0x00 -#define CARD_SHARE_SD 0x01 -#define CARD_SHARE_MS 0x02 -#define CARD_SHARE_MASK 0x03 - -/* CARD_AUTO_BLINK */ -#define BLINK_ENABLE 0x08 -#define BLINK_SPEED_MASK 0x07 - -/* CARD_GPIO */ -#define GPIO_OE 0x02 -#define GPIO_OUTPUT 0x01 - -/* CARD_CLK_SOURCE */ -#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) - -/* DCM_DRP_CTL */ -#define DCM_RESET 0x08 -#define DCM_LOCKED 0x04 -#define DCM_208M 0x00 -#define DCM_TX 0x01 -#define DCM_RX 0x02 - -/* DCM_DRP_TRIG */ -#define DRP_START 0x80 -#define DRP_DONE 0x40 - -/* DCM_DRP_CFG */ -#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 - -/* HW_VERSION */ -#define FPGA_VER 0x80 -#define HW_VER_MASK 0x0F - -/* CD_DEGLITCH_EN */ -#define DISABLE_SD_CD 0x08 -#define DISABLE_MS_CD 0x10 -#define DISABLE_XD_CD 0x20 -#define SD_CD_DEGLITCH_EN 0x01 -#define MS_CD_DEGLITCH_EN 0x02 -#define XD_CD_DEGLITCH_EN 0x04 - -/* OCPCTL */ -#define CARD_OC_DETECT_EN 0x08 -#define CARD_OC_CLR 0x01 - -/* CARD_DMA1_CTL */ -#define EXTEND_DMA1_ASYNC_SIGNAL 0x02 - -/* HS_USB_STAT */ -#define USB_HI_SPEED 0x01 - -/* CFG_MODE_1 */ -#define RTS5179 0x02 - -/* SYS_DUMMY0 */ -#define NYET_EN 0x01 -#define NYET_MSAK 0x01 - -/* SSC_CTL1 */ -#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 - -/* SSC_CTL2 */ -#define SSC_DEPTH_MASK 0x03 -#define SSC_DEPTH_DISALBE 0x00 -#define SSC_DEPTH_2M 0x01 -#define SSC_DEPTH_1M 0x02 -#define SSC_DEPTH_512K 0x03 - -/* LDO_POWER_CFG */ -#define TUNE_SD18_MASK 0x1C -#define TUNE_SD18_1V8 (0x01 << 2) -#define TUNE_SD18_3V3 (0x07 << 2) - -/* XD_CP_WAITTIME */ -#define WAIT_1F 0x00 -#define WAIT_3F 0x01 -#define WAIT_7F 0x02 -#define WAIT_FF 0x03 - -/* XD_INIT */ -#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 - -/* XD_DTCTL */ -/* XD_CATCTL */ -#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 - -/* XD_CTL */ -#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 - -/* XD_TRANSFER */ -#define XD_TRANSFER_START 0x80 -#define XD_TRANSFER_END 0x40 -#define XD_PPB_EMPTY 0x20 -#define XD_ERR 0x10 -#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_COPY_PAGES 0x0C - -/* XD_CFG */ -#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_MASK 0x07 -#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 - -/* XD_PAGE_STATUS */ -#define XD_GPG 0xFF -#define XD_BPG 0x00 - -/* XD_BLOCK_STATUS */ -#define XD_GBLK 0xFF -#define XD_LATER_BBLK 0xF0 - -/* XD_PARITY */ -#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 - -/* XD_CHK_DATA_STATUS */ -#define XD_PGSTS_ZEROBIT_OVER4 0x00 -#define XD_PGSTS_NOT_FF 0x02 -#define XD_AUTO_CHK_DATA_STATUS 0x01 - -/* SD_CFG1 */ -#define SD_CLK_DIVIDE_0 0x00 -#define SD_CLK_DIVIDE_256 0xC0 -#define SD_CLK_DIVIDE_128 0x80 -#define SD_CLK_DIVIDE_MASK 0xC0 -#define SD_BUS_WIDTH_1 0x00 -#define SD_BUS_WIDTH_4 0x01 -#define SD_BUS_WIDTH_8 0x02 -#define SD_ASYNC_FIFO_RST 0x10 -#define SD_20_MODE 0x00 -#define SD_DDR_MODE 0x04 -#define SD_30_MODE 0x08 - -/* SD_CFG2 */ -#define SD_CALCULATE_CRC7 0x00 -#define SD_NO_CALCULATE_CRC7 0x80 -#define SD_CHECK_CRC16 0x00 -#define SD_NO_CHECK_CRC16 0x40 -#define SD_WAIT_CRC_TO_EN 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 -/* SD/MMC Response Type Definition */ -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_NO_CHECK_CRC7, - * SD_RSP_LEN_0 */ -#define SD_RSP_TYPE_R0 0x04 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, - * SD_RSP_LEN_6 */ -#define SD_RSP_TYPE_R1 0x01 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_WAIT_BUSY_END, SD_CHECK_CRC7, - * SD_RSP_LEN_6 */ -#define SD_RSP_TYPE_R1b 0x09 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, - * SD_RSP_LEN_17 */ -#define SD_RSP_TYPE_R2 0x02 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_NO_CHECK_CRC7, - * SD_RSP_LEN_6 */ -#define SD_RSP_TYPE_R3 0x05 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_NO_CHECK_CRC7, - * SD_RSP_LEN_6 */ -#define SD_RSP_TYPE_R4 0x05 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, - * SD_RSP_LEN_6 */ -#define SD_RSP_TYPE_R5 0x01 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, - * SD_RSP_LEN_6 */ -#define SD_RSP_TYPE_R6 0x01 -/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, - * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, - * SD_RSP_LEN_6 */ -#define SD_RSP_TYPE_R7 0x01 - -/* SD_CFG3 */ -#define SD_RSP_80CLK_TIMEOUT_EN 0x01 - -/* SD_STAT1 */ -#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 - -/* SD_STAT2 */ -#define SD_RSP_80CLK_TIMEOUT 0x01 - -/* SD_BUS_STAT */ -#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 - -/* SD_PAD_CTL */ -#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 - -/* SD_SAMPLE_POINT_CTL */ -#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 - -/* SD_PUSH_POINT_CTL */ -#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 - -/* SD_TRANSFER */ -#define SD_TRANSFER_START 0x80 -#define SD_TRANSFER_END 0x40 -#define SD_STAT_IDLE 0x20 -#define SD_TRANSFER_ERR 0x10 -/* SD Transfer Mode definition */ -#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 - -/* SD_VPTX_CTL / SD_VPRX_CTL */ -#define PHASE_CHANGE 0x80 -#define PHASE_NOT_RESET 0x40 - -/* SD_DCMPS_TX_CTL / SD_DCMPS_RX_CTL */ -#define DCMPS_CHANGE 0x80 -#define DCMPS_CHANGE_DONE 0x40 -#define DCMPS_ERROR 0x20 -#define DCMPS_CURRENT_PHASE 0x1F - -/* SD_CMD_STATE */ -#define SD_CMD_IDLE 0x80 - -/* SD_DATA_STATE */ -#define SD_DATA_IDLE 0x80 - -/* MS_BLKEND */ -#define SET_BLKEND 0x01 - -/* MS_CFG */ -#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 - -/* MS_TRANS_CFG */ -#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 - -/* MS_TRANSFER */ -#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 MS_TM_SET_CMD 0x06 -#define MS_TM_COPY_PAGE 0x07 -#define MS_TM_MULTI_READ 0x02 -#define MS_TM_MULTI_WRITE 0x03 - -/* MC_DMA_CTL */ -#define DMA_TC_EQ_0 0x80 -#define DMA_DIR_TO_CARD 0x00 -#define DMA_DIR_FROM_CARD 0x02 -#define DMA_EN 0x01 -#define DMA_128 (0 << 2) -#define DMA_256 (1 << 2) -#define DMA_512 (2 << 2) -#define DMA_1024 (3 << 2) -#define DMA_PACK_SIZE_MASK 0x0C - -/* CARD_INT_PEND */ -#define XD_INT 0x10 -#define MS_INT 0x08 -#define SD_INT 0x04 - -/* MC_FIFO_CTL */ -#define FIFO_FLUSH 0x01 - -/* AUTO_DELINK_EN */ -#define AUTO_DELINK 0x02 -#define FORCE_DELINK 0x01 - -/* MC_DMA_RST */ -#define DMA_RESET 0x01 - -#define SSC_POWER_MASK 0x01 -#define SSC_POWER_DOWN 0x01 -#define SSC_POWER_ON 0x00 - -/* OCPCTL */ -#define MS_OCP_DETECT_EN 0x08 -#define MS_OCP_INT_EN 0x04 -#define MS_OCP_INT_CLR 0x02 -#define MS_OCP_CLEAR 0x01 - -/* OCPSTAT */ -#define MS_OCP_DETECT 0x80 -#define MS_OCP_NOW 0x02 -#define MS_OCP_EVER 0x01 - -/* MC_FIFO_STAT */ -#define FIFO_FULL 0x01 -#define FIFO_EMPTY 0x02 - -/* RCCTL */ -#define U_HW_CMD_EN_MASK 0x02 -#define U_HW_CMD_EN 0x02 -#define U_HW_CMD_DIS 0x00 - -/* Register address */ -#define FPDCTL 0xFC00 -#define SSC_DIV_N_0 0xFC07 -#define SSC_CTL1 0xFC09 -#define SSC_CTL2 0xFC0A -#define CFG_MODE_1 0xFC0F -#define RCCTL 0xFC14 -#define SYS_DUMMY0 0xFC30 -#define XD_CP_WAITTIME 0xFD00 -#define XD_CP_PAGELEN 0xFD01 -#define XD_CP_READADDR0 0xFD02 -#define XD_CP_READADDR1 0xFD03 -#define XD_CP_READADDR2 0xFD04 -#define XD_CP_READADDR3 0xFD05 -#define XD_CP_READADDR4 0xFD06 -#define XD_CP_WRITEADDR0 0xFD07 -#define XD_CP_WRITEADDR1 0xFD08 -#define XD_CP_WRITEADDR2 0xFD09 -#define XD_CP_WRITEADDR3 0xFD0A -#define XD_CP_WRITEADDR4 0xFD0B -#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_BLKEND 0xFD30 -#define MS_READ_START 0xFD31 -#define MS_READ_COUNT 0xFD32 -#define MS_WRITE_START 0xFD33 -#define MS_WRITE_COUNT 0xFD34 -#define MS_COMMAND 0xFD35 -#define MS_OLD_BLOCK_0 0xFD36 -#define MS_OLD_BLOCK_1 0xFD37 -#define MS_NEW_BLOCK_0 0xFD38 -#define MS_NEW_BLOCK_1 0xFD39 -#define MS_LOG_BLOCK_0 0xFD3A -#define MS_LOG_BLOCK_1 0xFD3B -#define MS_BUS_WIDTH 0xFD3C -#define MS_PAGE_START 0xFD3D -#define MS_PAGE_LENGTH 0xFD3E -#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 CARD_DMA1_CTL 0xFD5C -#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 CARD_EXIST 0xFD6F -#define CARD_INT_PEND 0xFD71 - -#define LDO_POWER_CFG 0xFD7B - -#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 SD_VPCLK0_CTL 0xFC2A -#define SD_VPCLK1_CTL 0xFC2B -#define SD_DCMPS0_CTL 0xFC2C -#define SD_DCMPS1_CTL 0xFC2D - -#define CARD_DMA1_CTL 0xFD5C - -#define HW_VERSION 0xFC01 - -#define SSC_CLK_FPGA_SEL 0xFC02 -#define CLK_DIV 0xFC03 -#define SFSM_ED 0xFC04 - -#define CD_DEGLITCH_WIDTH 0xFC20 -#define CD_DEGLITCH_EN 0xFC21 -#define AUTO_DELINK_EN 0xFC23 - -#define FPGA_PULL_CTL 0xFC1D -#define CARD_CLK_SOURCE 0xFC2E - -#define CARD_SHARE_MODE 0xFD51 -#define CARD_DRIVE_SEL 0xFD52 -#define CARD_STOP 0xFD53 -#define CARD_OE 0xFD54 -#define CARD_AUTO_BLINK 0xFD55 -#define CARD_GPIO 0xFD56 -#define SD30_DRIVE_SEL 0xFD57 - -#define CARD_DATA_SOURCE 0xFD5D -#define CARD_SELECT 0xFD5E - -#define CARD_CLK_EN 0xFD79 -#define CARD_PWR_CTL 0xFD7A - -#define OCPCTL 0xFD80 -#define OCPPARA1 0xFD81 -#define OCPPARA2 0xFD82 -#define OCPSTAT 0xFD83 - -#define HS_USB_STAT 0xFE01 -#define HS_VCONTROL 0xFE26 -#define HS_VSTAIN 0xFE27 -#define HS_VLOADM 0xFE28 -#define HS_VSTAOUT 0xFE29 - -#define MC_IRQ 0xFF00 -#define MC_IRQEN 0xFF01 -#define MC_FIFO_CTL 0xFF02 -#define MC_FIFO_BC0 0xFF03 -#define MC_FIFO_BC1 0xFF04 -#define MC_FIFO_STAT 0xFF05 -#define MC_FIFO_MODE 0xFF06 -#define MC_FIFO_RD_PTR0 0xFF07 -#define MC_FIFO_RD_PTR1 0xFF08 -#define MC_DMA_CTL 0xFF10 -#define MC_DMA_TC0 0xFF11 -#define MC_DMA_TC1 0xFF12 -#define MC_DMA_TC2 0xFF13 -#define MC_DMA_TC3 0xFF14 -#define MC_DMA_RST 0xFF15 - -/* Memory mapping */ -#define RBUF_SIZE_MASK 0xFBFF -#define RBUF_BASE 0xF000 -#define PPBUF_BASE1 0xF800 -#define PPBUF_BASE2 0xFA00 - -/* int monitor_card_cd */ -#define CD_EXIST 0 -#define CD_NOT_EXIST 1 - -#define DEBOUNCE_CNT 5 - -int monitor_card_cd(struct rts51x_chip *chip, u8 card); - -void rts51x_do_remaining_work(struct rts51x_chip *chip); -void rts51x_do_rts51x_reset_sd_card(struct rts51x_chip *chip); -void rts51x_init_cards(struct rts51x_chip *chip); -void rts51x_release_cards(struct rts51x_chip *chip); -int rts51x_switch_ssc_clock(struct rts51x_chip *chip, int clk); -int rts51x_switch_normal_clock(struct rts51x_chip *chip, int clk); -int rts51x_card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, - u32 sec_addr, u16 sec_cnt); -u8 rts51x_get_lun_card(struct rts51x_chip *chip, unsigned int lun); -int rts51x_select_card(struct rts51x_chip *chip, int card); -void rts51x_eject_card(struct rts51x_chip *chip, unsigned int lun); -void rts51x_trans_dma_enable(enum dma_data_direction dir, - struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size); -int rts51x_enable_card_clock(struct rts51x_chip *chip, u8 card); -int rts51x_card_power_on(struct rts51x_chip *chip, u8 card); -int rts51x_toggle_gpio(struct rts51x_chip *chip, u8 gpio); -int rts51x_turn_on_led(struct rts51x_chip *chip, u8 gpio); -int rts51x_turn_off_led(struct rts51x_chip *chip, u8 gpio); - -static inline int check_card_ready(struct rts51x_chip *chip, unsigned int lun) -{ - if (chip->card_ready & chip->lun2card[lun]) - return 1; - - return 0; -} - -static inline int check_card_exist(struct rts51x_chip *chip, unsigned int lun) -{ - if (chip->card_exist & chip->lun2card[lun]) - return 1; - - return 0; -} - -static inline int check_card_wp(struct rts51x_chip *chip, unsigned int lun) -{ - if (chip->card_wp & chip->lun2card[lun]) - return 1; - - return 0; -} - -static inline int check_card_fail(struct rts51x_chip *chip, unsigned int lun) -{ - if (chip->card_fail & chip->lun2card[lun]) - return 1; - - return 0; -} - -static inline int check_card_ejected(struct rts51x_chip *chip, unsigned int lun) -{ - if (chip->card_ejected & chip->lun2card[lun]) - return 1; - - return 0; -} - -static inline int check_fake_card_ready(struct rts51x_chip *chip, - unsigned int lun) -{ - if (chip->fake_card_ready & chip->lun2card[lun]) - return 1; - - return 0; -} - -static inline u8 get_lun2card(struct rts51x_chip *chip, unsigned int lun) -{ - return chip->lun2card[lun]; -} - -static inline int check_lun_mc(struct rts51x_chip *chip, unsigned int lun) -{ - return CHK_BIT(chip->lun_mc, lun); -} - -static inline void set_lun_mc(struct rts51x_chip *chip, unsigned int lun) -{ - SET_BIT(chip->lun_mc, lun); -} - -static inline void clear_lun_mc(struct rts51x_chip *chip, unsigned int lun) -{ - CLR_BIT(chip->lun_mc, lun); -} - -static inline int switch_clock(struct rts51x_chip *chip, int clk) -{ - int retval = 0; - - if (chip->asic_code) - retval = rts51x_switch_ssc_clock(chip, clk); - else - retval = rts51x_switch_normal_clock(chip, clk); - - return retval; -} - -static inline void rts51x_clear_xd_error(struct rts51x_chip *chip) -{ - rts51x_ep0_write_register(chip, CARD_STOP, - XD_STOP | XD_CLR_ERR, XD_STOP | XD_CLR_ERR); - - rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); - rts51x_ep0_write_register(chip, MC_DMA_RST, DMA_RESET, DMA_RESET); - rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); -} - -static inline void rts51x_clear_sd_error(struct rts51x_chip *chip) -{ - rts51x_ep0_write_register(chip, CARD_STOP, - SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); - - rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); - rts51x_ep0_write_register(chip, MC_DMA_RST, DMA_RESET, DMA_RESET); - rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); -} - -static inline void rts51x_clear_ms_error(struct rts51x_chip *chip) -{ - rts51x_ep0_write_register(chip, CARD_STOP, - MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); - - rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); - rts51x_ep0_write_register(chip, MC_DMA_RST, DMA_RESET, DMA_RESET); - rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); -} - -#endif /* __RTS51X_CARD_H */ diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c deleted file mode 100644 index 7d7510de170c..000000000000 --- a/drivers/staging/rts5139/rts51x_chip.c +++ /dev/null @@ -1,1014 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include "debug.h" -#include "trace.h" -#include "rts51x.h" -#include "rts51x_chip.h" -#include "rts51x_card.h" -#include "rts51x_transport.h" -#include "xd.h" -#include "ms.h" -#include "sd.h" - -static int check_sd_speed_prior(u32 sd_speed_prior) -{ - int i, fake_para = 0; - - /* Check the legality of sd_speed_prior */ - for (i = 0; i < 4; i++) { - u8 tmp = (u8) (sd_speed_prior >> (i * 8)); - if ((tmp < 0x01) || (tmp > 0x04)) { - fake_para = 1; - break; - } - } - - return !fake_para; -} - -int rts51x_reset_chip(struct rts51x_chip *chip) -{ - int retval; - - if (CHECK_PKG(chip, LQFP48)) { - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, LDO3318_PWR_MASK, - LDO_SUSPEND); - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, FORCE_LDO_POWERB, - FORCE_LDO_POWERB); - RTS51X_WRITE_REG(chip, CARD_PULL_CTL1, 0x30, 0x10); - RTS51X_WRITE_REG(chip, CARD_PULL_CTL5, 0x03, 0x01); - RTS51X_WRITE_REG(chip, CARD_PULL_CTL6, 0x0C, 0x04); - } - if (chip->asic_code) { - RTS51X_WRITE_REG(chip, SYS_DUMMY0, NYET_MSAK, NYET_EN); - RTS51X_WRITE_REG(chip, CD_DEGLITCH_WIDTH, 0xFF, 0x08); - rts51x_write_register(chip, CD_DEGLITCH_EN, XD_CD_DEGLITCH_EN, - 0x00); - rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, - chip->option.sd30_pad_drive); - rts51x_write_register(chip, CARD_DRIVE_SEL, SD20_DRIVE_MASK, - chip->option.sd20_pad_drive); - if (chip->rts5179) - rts51x_write_register(chip, CARD_PULL_CTL5, 0x03, 0x01); - if (CHECK_PKG(chip, LQFP48)) { - rts51x_write_register(chip, CARD_PULL_CTL3, - 0x80, 0x80); - rts51x_write_register(chip, CARD_PULL_CTL6, - 0xf0, 0xA0); - } else { - rts51x_write_register(chip, CARD_PULL_CTL1, - 0x30, 0x20); - rts51x_write_register(chip, CARD_PULL_CTL3, - 0x80, 0x80); - rts51x_write_register(chip, CARD_PULL_CTL6, - 0x0c, 0x08); - } - } - if (chip->option.sd_ctl & SUPPORT_UHS50_MMC44) { - SET_UHS50(chip); - RTS51X_DEBUGP("option enable UHS50&MMC44,sd_ctl:0x%x\n", - chip->option.sd_ctl); - } else { - /* if(CHECK_PID(chip, 0x0139)&&CHECK_PKG(chip, LQFP48)) */ - if ((CHECK_PID(chip, 0x0139) && CHECK_PKG(chip, LQFP48)) - || chip->rts5179) { - SET_UHS50(chip); - RTS51X_DEBUGP("PID enable UHS50&MMC44\n"); - } else { - CLEAR_UHS50(chip); - RTS51X_DEBUGP("PID disable UHS50&MMC44\n"); - } - } - - if (chip->option.ms_errreg_fix && (chip->ic_version > 1)) - rts51x_write_register(chip, 0xFD4D, 0x01, 0x01); - retval = rts51x_write_phy_register(chip, 0xC2, 0x7C); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - rts51x_init_cmd(chip); - - /* GPIO OE */ - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO, GPIO_OE, GPIO_OE); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, - EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#ifdef SUPPORT_OCP - if (chip->asic_code) { - rts51x_write_register(chip, OCPCTL, MS_OCP_DETECT_EN, - MS_OCP_DETECT_EN); - RTS51X_DEBUGP("Enable OCP detect!\n"); - } -#endif - if (chip->option.FT2_fast_mode) { - rts51x_card_power_on(chip, SD_CARD | MS_CARD | XD_CARD); - wait_timeout(10); - } - - return STATUS_SUCCESS; -} - -int rts51x_init_chip(struct rts51x_chip *chip) -{ - int retval; - u8 val; - - chip->max_lun = 0; - chip->cur_clk = 0; - chip->cur_card = 0; - - chip->card2lun[XD_CARD] = 0; - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 0; - chip->card_ejected = 0; - - chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; -#ifdef CLOSE_SSC_POWER - rts51x_write_register(chip, FPDCTL, SSC_POWER_MASK, SSC_POWER_ON); - udelay(100); - rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, 0x00); -#endif - RTS51X_SET_STAT(chip, STAT_RUN); - - RTS51X_READ_REG(chip, HW_VERSION, &val); - RTS51X_DEBUGP("HW_VERSION: 0x%x\n", val); - if (val & FPGA_VER) { - chip->asic_code = 0; - RTS51X_DEBUGP("FPGA!\n"); - } else { - chip->asic_code = 1; - RTS51X_DEBUGP("ASIC!\n"); - } - chip->ic_version = val & HW_VER_MASK; - - if (!check_sd_speed_prior(chip->option.sd_speed_prior)) - chip->option.sd_speed_prior = 0x01020403; - RTS51X_DEBUGP("sd_speed_prior = 0x%08x\n", - chip->option.sd_speed_prior); - - RTS51X_READ_REG(chip, CARD_SHARE_MODE, &val); - if (val & CARD_SHARE_LQFP_SEL) { - chip->package = LQFP48; - RTS51X_DEBUGP("Package: LQFP48\n"); - } else { - chip->package = QFN24; - RTS51X_DEBUGP("Package: QFN24\n"); - } - - RTS51X_READ_REG(chip, HS_USB_STAT, &val); - if (val & USB_HI_SPEED) { - chip->usb_speed = USB_20; - RTS51X_DEBUGP("USB High Speed\n"); - } else { - chip->usb_speed = USB_11; - RTS51X_DEBUGP("USB Full Speed\n"); - } - - RTS51X_READ_REG(chip, CFG_MODE_1, &val); - if (val & RTS5179) { - chip->rts5179 = 1; - RTS51X_DEBUGP("device is rts5179\n"); - } else { - chip->rts5179 = 0; - } - - retval = rts51x_reset_chip(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int rts51x_release_chip(struct rts51x_chip *chip) -{ - rts51x_xd_free_l2p_tbl(chip); - rts51x_ms_free_l2p_tbl(chip); - chip->card_ready = 0; - return STATUS_SUCCESS; -} - -static inline void rts51x_blink_led(struct rts51x_chip *chip) -{ - /* Read/Write */ - if (chip->card_ready) { - if (chip->led_toggle_counter < - chip->option.led_toggle_interval) { - chip->led_toggle_counter++; - } else { - chip->led_toggle_counter = 0; - rts51x_toggle_gpio(chip, LED_GPIO); - } - } -} - -static void rts51x_auto_delink_cmd(struct rts51x_chip *chip) -{ - rts51x_write_register(chip, AUTO_DELINK_EN, - AUTO_DELINK, AUTO_DELINK); -} - -static void rts51x_auto_delink_force_cmd(struct rts51x_chip *chip) -{ - rts51x_write_register(chip, AUTO_DELINK_EN, - AUTO_DELINK | FORCE_DELINK, - AUTO_DELINK | FORCE_DELINK); -} - -#ifdef USING_POLLING_CYCLE_DELINK -/* using polling cycle as delink time */ -static void rts51x_auto_delink_polling_cycle(struct rts51x_chip *chip) -{ - if (chip->auto_delink_counter <= - chip->option.delink_delay * 2) { - if (chip->auto_delink_counter == - chip->option.delink_delay) { - if (chip->card_exist) { - /* False card */ - if (!chip->card_ejected) { - /* if card is not ejected or safely - * remove,then do force delink */ - RTS51X_DEBUGP("False card inserted," - "do force delink\n"); - rts51x_auto_delink_force_cmd(chip); - chip->auto_delink_counter = - chip->option.delink_delay * 2 + 1; - } - } else { - RTS51X_DEBUGP("No card inserted, do delink\n"); - /* rts51x_write_register(chip, CARD_PWR_CTL, - DV3318_AUTO_PWR_OFF, 0); */ - rts51x_auto_delink_cmd(chip); - } - } - if (chip->auto_delink_counter == - chip->option.delink_delay * 2) { - RTS51X_DEBUGP("Try to do force delink\n"); - rts51x_auto_delink_force_cmd(chip); - } - chip->auto_delink_counter++; - } -} - -static void rts51x_auto_delink(struct rts51x_chip *chip) -{ - rts51x_auto_delink_polling_cycle(chip); -} -#else -/* some of called funcs are not implemented, so comment it out */ -static void rts51x_auto_delink(struct rts51x_chip *chip) -{ -} -#endif - -void rts51x_polling_func(struct rts51x_chip *chip) -{ - - rts51x_init_cards(chip); - -#ifdef SUPPORT_OCP - /* if OCP happen and card exist, then close card OE */ - if ((chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) && - (chip->card_exist)) { - - rts51x_prepare_run(chip); - - if (chip->card_exist & SD_CARD) - rts51x_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - else if (chip->card_exist & MS_CARD) - rts51x_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - else if (chip->card_exist & XD_CARD) - rts51x_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - } -#endif - - if (chip->idle_counter < IDLE_MAX_COUNT) { - chip->idle_counter++; - } else { - if (!RTS51X_CHK_STAT(chip, STAT_IDLE)) { - RTS51X_DEBUGP("Idle state!\n"); - RTS51X_SET_STAT(chip, STAT_IDLE); - chip->led_toggle_counter = 0; - /* Idle state, turn off LED - * to reduce power consumption */ - if (chip->option.led_always_on - && (chip->card_exist & - (SD_CARD | MS_CARD | XD_CARD)) - && (!chip->card_ejected)) { - rts51x_turn_on_led(chip, LED_GPIO); - } else { - if (chip->rts5179) { - rts51x_ep0_write_register(chip, - CARD_GPIO, - 0x03, 0x00); - } else { - rts51x_turn_off_led(chip, LED_GPIO); - } - - } - -#ifdef CLOSE_SSC_POWER - if (!chip->card_ready) { - rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, - CLK_CHANGE); - rts51x_write_register(chip, FPDCTL, - SSC_POWER_MASK, - SSC_POWER_DOWN); - RTS51X_DEBUGP("Close SSC clock power!\n"); - } -#endif - } - } - - switch (RTS51X_GET_STAT(chip)) { - case STAT_RUN: - rts51x_blink_led(chip); - rts51x_do_remaining_work(chip); - break; - - case STAT_IDLE: - break; - - default: - break; - } - - if (chip->option.auto_delink_en && !chip->card_ready) - rts51x_auto_delink(chip); - else - chip->auto_delink_counter = 0; -} - -void rts51x_add_cmd(struct rts51x_chip *chip, - u8 cmd_type, u16 reg_addr, u8 mask, u8 data) -{ - int i; - - if (chip->cmd_idx < ((CMD_BUF_LEN - CMD_OFFSET) / 4)) { - i = CMD_OFFSET + chip->cmd_idx * 4; - chip->cmd_buf[i++] = - ((cmd_type & 0x03) << 6) | (u8) ((reg_addr >> 8) & 0x3F); - chip->cmd_buf[i++] = (u8) reg_addr; - chip->cmd_buf[i++] = mask; - chip->cmd_buf[i++] = data; - chip->cmd_idx++; - } -} - -int rts51x_send_cmd(struct rts51x_chip *chip, u8 flag, int timeout) -{ - int result; - - chip->cmd_buf[CNT_H] = (u8) (chip->cmd_idx >> 8); - chip->cmd_buf[CNT_L] = (u8) (chip->cmd_idx); - chip->cmd_buf[STAGE_FLAG] = flag; - - result = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), - (void *)(chip->cmd_buf), - chip->cmd_idx * 4 + CMD_OFFSET, - 0, NULL, timeout, MODE_C); - if (result != STATUS_SUCCESS) - TRACE_RET(chip, result); - - return STATUS_SUCCESS; -} - -int rts51x_get_rsp(struct rts51x_chip *chip, int rsp_len, int timeout) -{ - int result; - - if (rsp_len <= 0) - TRACE_RET(chip, STATUS_ERROR); - /* rsp_len must aligned to dword */ - if (rsp_len % 4) - rsp_len += (4 - rsp_len % 4); - - result = rts51x_transfer_data_rcc(chip, RCV_BULK_PIPE(chip), - (void *)chip->rsp_buf, rsp_len, - 0, NULL, timeout, STAGE_R); - if (result != STATUS_SUCCESS) - TRACE_RET(chip, result); - - return STATUS_SUCCESS; -} - -int rts51x_get_card_status(struct rts51x_chip *chip, u16 *status) -{ - int retval; - u16 val; - -#ifdef GET_CARD_STATUS_USING_EPC - retval = rts51x_get_epc_status(chip, &val); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#else - retval = rts51x_ctrl_transfer(chip, RCV_CTRL_PIPE(chip), 0x02, 0xC0, - 0, 0, &val, 2, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#endif - - if (status) - *status = val; - - return STATUS_SUCCESS; -} - -int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data) -{ - int retval; - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, addr, mask, data); - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 *data) -{ - int retval; - - if (data) - *data = 0; - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, READ_REG_CMD, addr, 0, 0); - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rts51x_get_rsp(chip, 1, 100); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (data) - *data = chip->rsp_buf[0]; - - return STATUS_SUCCESS; -} - -int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, - u8 data) -{ - int retval; - u16 value = 0, index = 0; - - value |= (u16) (3 & 0x03) << 14; - value |= (u16) (addr & 0x3FFF); - index |= (u16) mask << 8; - index |= (u16) data; - - retval = rts51x_ctrl_transfer(chip, SND_CTRL_PIPE(chip), 0x00, 0x40, - cpu_to_be16(value), cpu_to_be16(index), - NULL, 0, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 *data) -{ - int retval; - u16 value = 0; - u8 val; - - if (data) - *data = 0; - - value |= (u16) (2 & 0x03) << 14; - value |= (u16) (addr & 0x3FFF); - - retval = rts51x_ctrl_transfer(chip, RCV_CTRL_PIPE(chip), 0x00, 0xC0, - cpu_to_be16(value), 0, &val, 1, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (data) - *data = val; - - return STATUS_SUCCESS; -} - -int rts51x_seq_write_register(struct rts51x_chip *chip, u16 addr, u16 len, - u8 *data) -{ - int result; - u16 cmd_len = len + 12; - - if (!data) - TRACE_RET(chip, STATUS_ERROR); - - cmd_len = (cmd_len <= CMD_BUF_LEN) ? cmd_len : CMD_BUF_LEN; - - /* cmd_len must aligned to dword */ - if (cmd_len % 4) - cmd_len += (4 - cmd_len % 4); - - chip->cmd_buf[0] = 'R'; - chip->cmd_buf[1] = 'T'; - chip->cmd_buf[2] = 'C'; - chip->cmd_buf[3] = 'R'; - chip->cmd_buf[PACKET_TYPE] = SEQ_WRITE; - chip->cmd_buf[5] = (u8) (len >> 8); - chip->cmd_buf[6] = (u8) len; - chip->cmd_buf[STAGE_FLAG] = 0; - chip->cmd_buf[8] = (u8) (addr >> 8); - chip->cmd_buf[9] = (u8) addr; - - memcpy(chip->cmd_buf + 12, data, len); - - result = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), - (void *)(chip->cmd_buf), cmd_len, 0, - NULL, 100, MODE_C); - if (result != STATUS_SUCCESS) - TRACE_RET(chip, result); - - return STATUS_SUCCESS; -} - -int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len, - u8 *data) -{ - int result; - u16 rsp_len; - - if (!data) - TRACE_RET(chip, STATUS_ERROR); - /* rsp_len must aligned to dword */ - if (len % 4) - rsp_len = len + (4 - len % 4); - else - rsp_len = len; - - chip->cmd_buf[0] = 'R'; - chip->cmd_buf[1] = 'T'; - chip->cmd_buf[2] = 'C'; - chip->cmd_buf[3] = 'R'; - chip->cmd_buf[PACKET_TYPE] = SEQ_READ; - chip->cmd_buf[5] = (u8) (rsp_len >> 8); - chip->cmd_buf[6] = (u8) rsp_len; - chip->cmd_buf[STAGE_FLAG] = STAGE_R; - chip->cmd_buf[8] = (u8) (addr >> 8); - chip->cmd_buf[9] = (u8) addr; - - result = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), - (void *)(chip->cmd_buf), 12, 0, NULL, - 100, MODE_C); - if (result != STATUS_SUCCESS) - TRACE_RET(chip, result); - - result = rts51x_transfer_data_rcc(chip, RCV_BULK_PIPE(chip), - (void *)data, rsp_len, 0, NULL, 100, - STAGE_DI); - if (result != STATUS_SUCCESS) - TRACE_RET(chip, result); - - return STATUS_SUCCESS; -} - -int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len) -{ - int retval; - - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - retval = - rts51x_seq_read_register(chip, PPBUF_BASE2, (u16) buf_len, buf); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len) -{ - int retval; - - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - retval = - rts51x_seq_write_register(chip, PPBUF_BASE2, (u16) buf_len, buf); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_write_phy_register(struct rts51x_chip *chip, u8 addr, u8 val) -{ - int retval; - - RTS51X_DEBUGP("Write 0x%x to phy register 0x%x\n", val, addr); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VSTAIN, 0xFF, val); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, - (addr >> 4) & 0x0F); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 *val) -{ - int retval; - - RTS51X_DEBUGP("Read from phy register 0x%x\n", addr); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, 0x07); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, - (addr >> 4) & 0x0F); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); - rts51x_add_cmd(chip, READ_REG_CMD, HS_VSTAOUT, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 1, 100); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (val) - *val = chip->rsp_buf[0]; - - RTS51X_DEBUGP("Return value: 0x%x\n", chip->rsp_buf[0]); - - return STATUS_SUCCESS; -} - -void rts51x_do_before_power_down(struct rts51x_chip *chip) -{ - RTS51X_DEBUGP("rts51x_do_before_power_down\n"); - - rts51x_prepare_run(chip); - - rts51x_release_cards(chip); - if (chip->rts5179) - rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, 0x00); - else - rts51x_turn_off_led(chip, LED_GPIO); - - chip->cur_clk = 0; - chip->card_exist = 0; - chip->cur_card = 0; - if (chip->asic_code) { - if (CHECK_PKG(chip, LQFP48)) { - rts51x_write_register(chip, CARD_PULL_CTL3, 0x80, 0x00); - rts51x_write_register(chip, CARD_PULL_CTL6, 0xf0, 0x50); - } else { - rts51x_write_register(chip, CARD_PULL_CTL1, 0x30, 0x10); - rts51x_write_register(chip, CARD_PULL_CTL3, 0x80, 0x00); - rts51x_write_register(chip, CARD_PULL_CTL6, 0x0c, 0x04); - } - } - if (CHECK_PKG(chip, LQFP48)) - rts51x_write_register(chip, CARD_PWR_CTL, LDO3318_PWR_MASK, - LDO_OFF); -} - -void rts51x_clear_hw_error(struct rts51x_chip *chip) -{ - rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); -} - -void rts51x_prepare_run(struct rts51x_chip *chip) -{ -#ifdef CLOSE_SSC_POWER - if (RTS51X_CHK_STAT(chip, STAT_IDLE) && (!chip->card_ready)) { - rts51x_write_register(chip, FPDCTL, SSC_POWER_MASK, - SSC_POWER_ON); - udelay(100); - RTS51X_DEBUGP("Open SSC clock power.\n"); - - rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, 0x00); - } -#endif -} - -#ifdef _MSG_TRACE -void rts51x_trace_msg(struct rts51x_chip *chip, unsigned char *buf, int clear) -{ - unsigned char *ptr; - int i, msg_cnt; - - if (!buf) - return; - - ptr = buf; - - if (chip->trace_msg[chip->msg_idx].valid) - msg_cnt = TRACE_ITEM_CNT; - else - msg_cnt = chip->msg_idx; - *(ptr++) = (u8) (msg_cnt >> 24); - *(ptr++) = (u8) (msg_cnt >> 16); - *(ptr++) = (u8) (msg_cnt >> 8); - *(ptr++) = (u8) msg_cnt; - RTS51X_DEBUGP("Trace message count is %d\n", msg_cnt); - - for (i = 1; i <= msg_cnt; i++) { - int j, idx; - - idx = chip->msg_idx - i; - if (idx < 0) - idx += TRACE_ITEM_CNT; - - *(ptr++) = (u8) (chip->trace_msg[idx].line >> 8); - *(ptr++) = (u8) (chip->trace_msg[idx].line); - for (j = 0; j < MSG_FUNC_LEN; j++) - *(ptr++) = chip->trace_msg[idx].func[j]; - for (j = 0; j < MSG_FILE_LEN; j++) - *(ptr++) = chip->trace_msg[idx].file[j]; - for (j = 0; j < TIME_VAL_LEN; j++) - *(ptr++) = chip->trace_msg[idx].timeval_buf[j]; - } - - if (clear) { - chip->msg_idx = 0; - for (i = 0; i < TRACE_ITEM_CNT; i++) - chip->trace_msg[i].valid = 0; - } -} -#endif - -void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, - u8 status_len) -{ - struct sd_info *sd_card = &(chip->sd_card); - struct ms_info *ms_card = &(chip->ms_card); - u8 card = rts51x_get_lun_card(chip, lun); -#ifdef SUPPORT_OC - u8 oc_now_mask = 0, oc_ever_mask = 0; -#endif - - if (!status || (status_len < 32)) - return; - /* IC Version */ - status[0] = (u8) RTS51X_GET_PID(chip); - status[1] = (u8) (chip->ic_version); - - /* Auto delink mode */ - if (chip->option.auto_delink_en) - status[2] = 0x10; - else - status[2] = 0x00; - - /* Spec version */ - status[3] = 20; - status[4] = 10; - status[5] = 05; - status[6] = 21; - - /* Card WP */ - if (chip->card_wp) - status[7] = 0x20; - else - status[7] = 0x00; - -#ifdef SUPPORT_OC - /* Over current status */ - status[8] = 0; - oc_now_mask = MS_OCP_NOW; - oc_ever_mask = MS_OCP_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) - /* SDXC */ - status[0x0E] = 0x02; - else /* SDHC */ - status[0x0E] = 0x01; - } else { /* SDSC */ - 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; /* Normal speed */ - } else { - if (CHK_MMC_SECTOR_MODE(sd_card)) - status[0x0E] = 0x01; /* High capacity */ - else - status[0x0E] = 0x00; /* Normal capacity */ - - if (CHK_MMC_DDR52(sd_card)) - status[0x0F] = 0x03; /* DDR 52M */ - else if (CHK_MMC_52M(sd_card)) - status[0x0F] = 0x02; /* SDR 52M */ - else if (CHK_MMC_26M(sd_card)) - status[0x0F] = 0x01; /* SDR 26M */ - else - status[0x0F] = 0x00; /* Normal speed */ - } - } else if (card == MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (CHK_MSXC(ms_card)) - status[0x0E] = 0x01; /* XC */ - else - status[0x0E] = 0x00; - - if (CHK_HG8BIT(ms_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } - } - - /* Function 0 - * Support Magic Gate, CPRM and PhyRegister R/W */ - status[0x18] = 0x8A; - - /* Function 2 - * Support OC LUN status & WP LUN status */ - status[0x1A] = 0x28; - - /* Function 2 - * Support OC LUN status & WP LUN status */ - status[0x1A] = 0x28; -} - -void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun, - u8 *rts51x_status, u8 status_len) -{ - if (!rts51x_status || (status_len < 16)) - return; - /* VID */ - rts51x_status[0] = (u8) (RTS51X_GET_VID(chip) >> 8); - rts51x_status[1] = (u8) RTS51X_GET_VID(chip); - - /* PID */ - rts51x_status[2] = (u8) (RTS51X_GET_PID(chip) >> 8); - rts51x_status[3] = (u8) RTS51X_GET_PID(chip); - - /* gbLUN */ - rts51x_status[4] = (u8) lun; - - /* Lun Card Number */ - if (chip->card_exist) { - if (chip->card_exist & XD_CARD) - rts51x_status[5] = 4; /* xD Card */ - else if (chip->card_exist & SD_CARD) - rts51x_status[5] = 2; /* SD Card */ - else if (chip->card_exist & MS_CARD) - rts51x_status[5] = 3; /* MS Card */ - else - rts51x_status[5] = 7; /* Multi */ - } else { - rts51x_status[5] = 7; /* Multi */ - } - - /* Total LUNs */ - rts51x_status[6] = 1; - - /* IC Version */ - rts51x_status[7] = (u8) RTS51X_GET_PID(chip); - rts51x_status[8] = chip->ic_version; - - /* Physical Exist */ - if (check_card_exist(chip, lun)) - rts51x_status[9] = 1; - else - rts51x_status[9] = 0; - - /* Multi Flag */ - rts51x_status[10] = 1; - - /* LUN Valid Map */ - rts51x_status[11] = XD_CARD | SD_CARD | MS_CARD; - - /* Logical Exist */ - if (check_card_ready(chip, lun)) - rts51x_status[12] = 1; - else - rts51x_status[12] = 0; - - /* Detailed Type */ - if (rts51x_get_lun_card(chip, lun) == XD_CARD) { - rts51x_status[13] = 0x40; - } else if (rts51x_get_lun_card(chip, lun) == SD_CARD) { - struct sd_info *sd_card = &(chip->sd_card); - - rts51x_status[13] = 0x20; - if (CHK_SD(sd_card)) { - if (CHK_SD_HCXC(sd_card)) - rts51x_status[13] |= 0x04; /* Hi capacity SD */ - if (CHK_SD_HS(sd_card)) - rts51x_status[13] |= 0x02; /* Hi speed SD */ - } else { - rts51x_status[13] |= 0x08; /* MMC card */ - if (CHK_MMC_52M(sd_card)) - rts51x_status[13] |= 0x02; /* Hi speed */ - if (CHK_MMC_SECTOR_MODE(sd_card)) - rts51x_status[13] |= 0x04; /* Hi capacity */ - } - } else if (rts51x_get_lun_card(chip, lun) == MS_CARD) { - struct ms_info *ms_card = &(chip->ms_card); - - if (CHK_MSPRO(ms_card)) { - rts51x_status[13] = 0x38; /* MS Pro */ - if (CHK_HG8BIT(ms_card)) - rts51x_status[13] |= 0x04; /* HG */ -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) - rts51x_status[13] |= 0x01; /* MSXC */ -#endif - } else { - rts51x_status[13] = 0x30; - } - } else { - rts51x_status[13] = 0x70; - } -/* Support OC, auto delink, vendor r/w, get bus width */ - rts51x_status[14] = 0x78; - - rts51x_status[15] = 0x82; -} - -int rts51x_transfer_data_rcc(struct rts51x_chip *chip, unsigned int pipe, - void *buf, unsigned int len, int use_sg, - unsigned int *act_len, int timeout, u8 stage_flag) -{ - int retval; - - retval = - rts51x_transfer_data(chip, pipe, buf, len, use_sg, act_len, - timeout); - - return retval; - -} diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h deleted file mode 100644 index 12deb24cfbbe..000000000000 --- a/drivers/staging/rts5139/rts51x_chip.h +++ /dev/null @@ -1,821 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_CHIP_H -#define __RTS51X_CHIP_H - -#include -#include -#include -#include -#include -#include - -#include "trace.h" - -#define SUPPORT_CPRM -#define SUPPORT_MAGIC_GATE -#define SUPPORT_MSXC -#define USING_POLLING_CYCLE_DELINK - -#ifdef SUPPORT_MAGIC_GA -/* Using NORMAL_WRITE instead of AUTO_WRITE to set ICVTE */ -#define MG_SET_ICV_SLOW -#endif - -#ifdef SUPPORT_MSXC -#define XC_POWERCLASS -#define SUPPORT_PCGL_1P18 -#endif - -#define GET_CARD_STATUS_USING_EPC - -#define CLOSE_SSC_POWER - -#define SUPPORT_OCP - -#define MS_SPEEDUP - -#define SD_XD_IO_FOLLOW_PWR - -#define SD_NR 2 -#define MS_NR 3 -#define XD_NR 4 -#define SD_CARD (1 << SD_NR) -#define MS_CARD (1 << MS_NR) -#define XD_CARD (1 << XD_NR) - -#define SD_CD 0x01 -#define MS_CD 0x02 -#define XD_CD 0x04 -#define SD_WP 0x08 - -#define MAX_ALLOWED_LUN_CNT 8 -#define CMD_BUF_LEN 1024 -#define POLLING_INTERVAL 50 /* 50ms */ - -#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))) - -/* Command type */ -#define READ_REG_CMD 0 -#define WRITE_REG_CMD 1 -#define CHECK_REG_CMD 2 - -#define PACKET_TYPE 4 -#define CNT_H 5 -#define CNT_L 6 -#define STAGE_FLAG 7 -#define CMD_OFFSET 8 - -/* Packet type */ -#define BATCH_CMD 0 -#define SEQ_READ 1 -#define SEQ_WRITE 2 - -/* Stage flag */ -#define STAGE_R 0x01 -#define STAGE_DI 0x02 -#define STAGE_DO 0x04 -/* Return MS_TRANS_CFG, GET_INT */ -#define STAGE_MS_STATUS 0x08 -/* Return XD_CFG, XD_CTL, XD_PAGE_STATUS */ -#define STAGE_XD_STATUS 0x10 -/* Command stage mode */ -#define MODE_C 0x00 -#define MODE_CR (STAGE_R) -#define MODE_CDIR (STAGE_R | STAGE_DI) -#define MODE_CDOR (STAGE_R | STAGE_DO) - -/* Function return code */ -#ifndef STATUS_SUCCESS -#define STATUS_SUCCESS 0 -#endif - -#define STATUS_FAIL 1 -#define STATUS_TIMEDOUT 4 -#define STATUS_NOMEM 5 -#define STATUS_TRANS_SHORT 6 -#define STATUS_TRANS_LONG 7 -#define STATUS_STALLED 8 -#define STATUS_ERROR 10 - -#define IDLE_MAX_COUNT 10 -#define POLLING_WAIT_CNT 1 -#define LED_GPIO 0 - -/* package */ -#define QFN24 0 -#define LQFP48 1 - -#define USB_11 0 -#define USB_20 1 - -/* - * Transport return codes - */ -/* Transport good, command good */ -#define TRANSPORT_GOOD 0 -/* Transport good, command failed */ -#define TRANSPORT_FAILED 1 -/* Transport bad (i.e. device dead) */ -#define TRANSPORT_ERROR 3 - -/* Supported Clock */ -enum card_clock { CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, CLK_80, CLK_100 }; - -#ifdef _MSG_TRACE - -#define TRACE_ITEM_CNT 64 - -struct trace_msg_t { - u16 line; -#define MSG_FUNC_LEN 64 - char func[MSG_FUNC_LEN]; -#define MSG_FILE_LEN 32 - char file[MSG_FILE_LEN]; -#define TIME_VAL_LEN 16 - u8 timeval_buf[TIME_VAL_LEN]; - u8 valid; -}; - -#endif /* _MSG_TRACE */ - -/* Size of the autosense data buffer */ -#define SENSE_SIZE 18 - -/* 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_CMD_FAILED 10 -#ifdef SUPPORT_MAGIC_GATE -/* COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED */ -#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b -/* COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE */ -#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c -/* INCOMPATIBLE MEDIUM INSTALLED */ -#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d -/* WRITE ERROR */ -#define SENSE_TYPE_MG_WRITE_ERR 0x0e -#endif - -/*---- sense key ----*/ -#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ - -/*----------------------------------- - SENSE_DATA ------------------------------------*/ - -/*---- error code ----*/ -#define CUR_ERR 0x70 /* current error */ - -/*---- sense key Information ----*/ - -#define SKSV 0x80 -#define CDB_ILLEGAL 0x40 - -/*---- ASC ----*/ -#define ASC_INVLD_CDB 0x24 - -/*---- ASQC ----*/ -#define ASCQ_INVLD_CDB 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 */ -}; - -/* 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 */ -#define SUPPORT_UHS50_MMC44 0x40 - -struct rts51x_option { - int rts51x_mspro_formatter_enable; - - /* card clock expected by user for fpga platform */ - 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; - - /* card clock expected by user for asic platform */ - 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; - - u8 ssc_depth_sd_sdr104; /* sw */ - u8 ssc_depth_sd_ddr50; /* sw */ - u8 ssc_depth_sd_sdr50; /* sw */ - u8 ssc_depth_sd_hs; /* sw */ - u8 ssc_depth_mmc_52m; /* sw */ - u8 ssc_depth_ms_hg; /* sw */ - u8 ssc_depth_ms_4bit; /* sw */ - u8 ssc_depth_low_speed; /* sw */ - - /* SD/MMC Tx phase */ - int sd_ddr_tx_phase; /* Enabled by bit 4 of sd_ctl */ - int mmc_ddr_tx_phase; /* Enabled by bit 5 of sd_ctl */ - - /* priority of choosing sd speed funciton */ - u32 sd_speed_prior; - - /* sd card control */ - u32 sd_ctl; - - /* Enable Selective Suspend */ - int ss_en; - /* Interval to enter SS from IDLE state (second) */ - int ss_delay; - - /* Enable SSC clock */ - int ssc_en; - - int auto_delink_en; - - /* sangdy2010-07-13:add FT2 fast mode */ - int FT2_fast_mode; - /* sangdy2010-07-15: - * add for config delay between 1/4 PMOS and 3/4 PMOS */ - int pwr_delay; - - int rts51x_xd_rw_step; /* add to tune xd tRP */ - int D3318_off_delay; /* add to tune D3318 off delay time */ - int delink_delay; /* add to tune delink delay time */ - /* add for rts5129 to enable/disable D3318 off */ - u8 rts5129_D3318_off_enable; - u8 sd20_pad_drive; /* add to config SD20 PAD drive */ - u8 sd30_pad_drive; /* add to config SD30 pad drive */ - /*if reset or rw fail,then set SD20 pad drive again */ - u8 reset_or_rw_fail_set_pad_drive; - - u8 debounce_num; /* debounce number */ - u8 led_toggle_interval; /* used to control led toggle speed */ - int rts51x_xd_rwn_step; - u8 sd_send_status_en; - /* used to store default phase which is - * used when phase tune all pass. */ - u8 ddr50_tx_phase; - u8 ddr50_rx_phase; - u8 sdr50_tx_phase; - u8 sdr50_rx_phase; - /* used to enable select sdr50 tx phase according to proportion. */ - u8 sdr50_phase_sel; - u8 ms_errreg_fix; - u8 reset_mmc_first; - u8 speed_mmc; /* when set, then try CMD55 only twice */ - u8 led_always_on; /* if set, then led always on when card exist */ - u8 dv18_voltage; /* add to tune dv18 voltage */ -}; - -#define MS_FORMATTER_ENABLED(chip) ((chip)->option.rts51x_mspro_formatter_enable) - -struct rts51x_chip; - -typedef int (*rts51x_card_rw_func) (struct scsi_cmnd *srb, struct rts51x_chip *chip, - u32 sec_addr, u16 sec_cnt); - -/* 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; -}; - -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 counter; - - int xd_clock; -}; - -#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_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) -#define CLR_SD30_SPEED(sd_card) \ - ((sd_card)->sd_type &= ~(SD_SDR50|SD_DDR50|SD_SDR104)) - -/* 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) -#define CLR_RETRY_SD20_MODE(sd_card) \ - ((sd_card)->retry_SD20_mode = 0) -#define SET_RETRY_SD20_MODE(sd_card) \ - ((sd_card)->retry_SD20_mode = 1) -#define CHK_RETRY_SD20_MODE(sd_card) \ - ((sd_card)->retry_SD20_mode == 1) - -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 counter; - - int sd_clock; - -#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; - u8 retry_SD20_mode; /* sangdy2010-06-10 */ - u8 sd_reset_fail; /* sangdy2010-07-01 */ - u8 sd_send_status_en; - -}; - -#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 rts51x_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; - u8 last_rw_int; - - struct rts51x_ms_delay_write_tag delay_write; - - int 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 -}; - -#define PRO_UNDER_FORMATTING(ms_card) \ - ((ms_card)->pro_under_formatting) -#define SET_FORMAT_STATUS(ms_card, status) \ - ((ms_card)->format_status = (status)) -#define CHK_FORMAT_STATUS(ms_card, status) \ - ((ms_card)->format_status == (status)) - -struct scsi_cmnd; - -enum CHIP_STAT { STAT_INIT, STAT_IDLE, STAT_RUN, STAT_SS_PRE, STAT_SS, - STAT_SUSPEND }; - -struct rts51x_chip { - u16 vendor_id; - u16 product_id; - char max_lun; - - struct scsi_cmnd *srb; - struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; - - int led_toggle_counter; - - int ss_counter; - int idle_counter; - int auto_delink_counter; - enum CHIP_STAT chip_stat; - - int resume_from_scsi; - - /* Card information */ - struct xd_info xd_card; - struct sd_info sd_card; - struct ms_info ms_card; - - int cur_clk; /* current card clock */ - int cur_card; /* Current card module */ - - 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 fake_card_ready; - /* flag to indicate whether to answer MediaChange */ - unsigned long lun_mc; - - /* card bus width */ - u8 card_bus_width[MAX_ALLOWED_LUN_CNT]; - /* card capacity */ - u32 capacity[MAX_ALLOWED_LUN_CNT]; - - /* read/write card function pointer */ - rts51x_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]; - -#ifdef _MSG_TRACE - struct trace_msg_t trace_msg[TRACE_ITEM_CNT]; - int msg_idx; -#endif - - int rw_need_retry; - - /* ASIC or FPGA */ - int asic_code; - - /* QFN24 or LQFP48 */ - int package; - - /* Full Speed or High Speed */ - int usb_speed; - - /*sangdy:enable or disable UHS50 and MMC4.4 */ - int uhs50_mmc44_en; - - u8 ic_version; - - /* Command buffer */ - u8 *cmd_buf; - unsigned int cmd_idx; - /* Response buffer */ - u8 *rsp_buf; - - u16 card_status; - -#ifdef SUPPORT_OCP - u16 ocp_stat; -#endif - - struct rts51x_option option; - struct rts51x_usb *usb; - - u8 rcc_read_response; - int reset_need_retry; - u8 rts5179; -}; - -#define UHS50_EN 0x0001 -#define UHS50_DIS 0x0000 -#define SET_UHS50(chip) ((chip)->uhs50_mmc44_en = UHS50_EN) -#define CLEAR_UHS50(chip) ((chip)->uhs50_mmc44_en = UHS50_DIS) -#define CHECK_UHS50(chip) (((chip)->uhs50_mmc44_en&0xff) == UHS50_EN) - -#define RTS51X_GET_VID(chip) ((chip)->vendor_id) -#define RTS51X_GET_PID(chip) ((chip)->product_id) - -#define RTS51X_SET_STAT(chip, stat) \ -do { \ - if ((stat) != STAT_IDLE) { \ - (chip)->idle_counter = 0; \ - } \ - (chip)->chip_stat = (enum CHIP_STAT)(stat); \ -} while (0) -#define RTS51X_CHK_STAT(chip, stat) ((chip)->chip_stat == (stat)) -#define RTS51X_GET_STAT(chip) ((chip)->chip_stat) - -#define CHECK_PID(chip, pid) (RTS51X_GET_PID(chip) == (pid)) -#define CHECK_PKG(chip, pkg) ((chip)->package == (pkg)) -#define CHECK_USB(chip, speed) ((chip)->usb_speed == (speed)) - -int rts51x_reset_chip(struct rts51x_chip *chip); -int rts51x_init_chip(struct rts51x_chip *chip); -int rts51x_release_chip(struct rts51x_chip *chip); -void rts51x_polling_func(struct rts51x_chip *chip); - -static inline void rts51x_init_cmd(struct rts51x_chip *chip) -{ - chip->cmd_idx = 0; - chip->cmd_buf[0] = 'R'; - chip->cmd_buf[1] = 'T'; - chip->cmd_buf[2] = 'C'; - chip->cmd_buf[3] = 'R'; - chip->cmd_buf[PACKET_TYPE] = BATCH_CMD; -} - -void rts51x_add_cmd(struct rts51x_chip *chip, - u8 cmd_type, u16 reg_addr, u8 mask, u8 data); -int rts51x_send_cmd(struct rts51x_chip *chip, u8 flag, int timeout); -int rts51x_get_rsp(struct rts51x_chip *chip, int rsp_len, int timeout); - -static inline void rts51x_read_rsp_buf(struct rts51x_chip *chip, int offset, - u8 *buf, int buf_len) -{ - memcpy(buf, chip->rsp_buf + offset, buf_len); -} - -static inline u8 *rts51x_get_rsp_data(struct rts51x_chip *chip) -{ - return chip->rsp_buf; -} - -int rts51x_get_card_status(struct rts51x_chip *chip, u16 *status); -int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data); -int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 *data); -int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, - u8 data); -int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 *data); -int rts51x_seq_write_register(struct rts51x_chip *chip, u16 addr, u16 len, - u8 *data); -int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len, - u8 *data); -int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len); -int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len); -int rts51x_write_phy_register(struct rts51x_chip *chip, u8 addr, u8 val); -int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 *val); -void rts51x_do_before_power_down(struct rts51x_chip *chip); -void rts51x_clear_hw_error(struct rts51x_chip *chip); -void rts51x_prepare_run(struct rts51x_chip *chip); -void rts51x_trace_msg(struct rts51x_chip *chip, unsigned char *buf, int clear); -void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, - u8 status_len); -void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun, - u8 *rts51x_status, u8 status_len); -int rts51x_transfer_data_rcc(struct rts51x_chip *chip, unsigned int pipe, - void *buf, unsigned int len, int use_sg, - unsigned int *act_len, int timeout, u8 stage_flag); - -#define RTS51X_WRITE_REG(chip, addr, mask, data) \ -do { \ - int _retval = rts51x_write_register((chip), \ - (addr), (mask), (data)); \ - if (_retval != STATUS_SUCCESS) { \ - TRACE_RET((chip), _retval); \ - } \ -} while (0) - -#define RTS51X_READ_REG(chip, addr, data) \ -do { \ - int _retval = rts51x_read_register((chip), \ - (addr), (data)); \ - if (_retval != STATUS_SUCCESS) { \ - TRACE_RET((chip), _retval); \ - } \ -} while (0) - -#endif /* __RTS51X_CHIP_H */ diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c deleted file mode 100644 index cf4e675aea69..000000000000 --- a/drivers/staging/rts5139/rts51x_fop.c +++ /dev/null @@ -1,295 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include "rts51x.h" - -#ifdef SUPPORT_FILE_OP - -#include -#include -#include -#include - -#include "rts51x_chip.h" -#include "rts51x_card.h" -#include "rts51x_fop.h" -#include "sd_cprm.h" - -#define RTS5139_IOC_MAGIC 0x39 - -#define RTS5139_IOC_SD_DIRECT _IOWR(RTS5139_IOC_MAGIC, 0xA0, int) -#define RTS5139_IOC_SD_GET_RSP _IOWR(RTS5139_IOC_MAGIC, 0xA1, int) - -static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip, - struct sd_direct_cmnd *cmnd) -{ - int retval; - u8 dir, cmd12, standby, acmd, cmd_idx, rsp_code; - u8 *buf; - u32 arg, len; - - dir = (cmnd->cmnd[0] >> 3) & 0x03; - cmd12 = (cmnd->cmnd[0] >> 2) & 0x01; - standby = (cmnd->cmnd[0] >> 1) & 0x01; - acmd = cmnd->cmnd[0] & 0x01; - cmd_idx = cmnd->cmnd[1]; - arg = ((u32) (cmnd->cmnd[2]) << 24) | ((u32) (cmnd->cmnd[3]) << 16) | - ((u32) (cmnd->cmnd[4]) << 8) | cmnd->cmnd[5]; - len = - ((u32) (cmnd->cmnd[6]) << 16) | ((u32) (cmnd->cmnd[7]) << 8) | - cmnd->cmnd[8]; - rsp_code = cmnd->cmnd[9]; - - if (dir) { - if (!cmnd->buf || (cmnd->buf_len < len)) - TRACE_RET(chip, STATUS_FAIL); - } - - switch (dir) { - case 0: - /* No data */ - retval = ext_rts51x_sd_execute_no_data(chip, - chip->card2lun[SD_CARD], - cmd_idx, standby, acmd, - rsp_code, arg); - if (retval != TRANSPORT_GOOD) - TRACE_RET(chip, STATUS_FAIL); - break; - - case 1: - /* Read from card */ - buf = kzalloc(cmnd->buf_len, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_NOMEM); - - retval = ext_rts51x_sd_execute_read_data(chip, - chip->card2lun[SD_CARD], - cmd_idx, cmd12, standby, acmd, - rsp_code, arg, len, buf, - cmnd->buf_len, 0); - if (retval != TRANSPORT_GOOD) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = - copy_to_user(cmnd->buf, (void *)buf, cmnd->buf_len); - if (retval) { - kfree(buf); - TRACE_RET(chip, STATUS_NOMEM); - } - - kfree(buf); - break; - - case 2: - /* Write to card */ - buf = kmalloc(cmnd->buf_len, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_NOMEM); - - retval = - copy_from_user((void *)buf, cmnd->buf, - cmnd->buf_len); - if (retval) { - kfree(buf); - TRACE_RET(chip, STATUS_NOMEM); - } - - retval = - ext_rts51x_sd_execute_write_data(chip, - chip->card2lun[SD_CARD], - cmd_idx, cmd12, standby, acmd, - rsp_code, arg, len, buf, - cmnd->buf_len, 0); - if (retval != TRANSPORT_GOOD) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - kfree(buf); - - break; - - default: - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int rts51x_sd_get_rsp(struct rts51x_chip *chip, struct sd_rsp *rsp) -{ - struct sd_info *sd_card = &(chip->sd_card); - int count = 0, retval; - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - TRACE_RET(chip, STATUS_FAIL); - } - - if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) - TRACE_RET(chip, STATUS_FAIL); - else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) - count = (rsp->rsp_len < 17) ? rsp->rsp_len : 17; - else - count = (rsp->rsp_len < 6) ? rsp->rsp_len : 6; - - retval = copy_to_user(rsp->rsp, (void *)sd_card->rsp, count); - if (retval) - TRACE_RET(chip, STATUS_NOMEM); - - RTS51X_DEBUGP("Response length: %d\n", count); - RTS51X_DEBUGP("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]); - - return STATUS_SUCCESS; -} - -int rts51x_open(struct inode *inode, struct file *filp) -{ - struct rts51x_chip *chip; - struct usb_interface *interface; - int subminor; - int retval = 0; - - subminor = iminor(inode); - - interface = usb_find_interface(&rts51x_driver, subminor); - if (!interface) { - RTS51X_DEBUGP("%s - error, can't find device for minor %d\n", - __func__, subminor); - retval = -ENODEV; - goto exit; - } - - chip = (struct rts51x_chip *)usb_get_intfdata(interface); - if (!chip) { - RTS51X_DEBUGP("Can't find chip\n"); - retval = -ENODEV; - goto exit; - } - - /* Increase our reference to the host */ - scsi_host_get(rts51x_to_host(chip)); - - /* lock the device pointers */ - mutex_lock(&(chip->usb->dev_mutex)); - - /* save our object in the file's private structure */ - filp->private_data = chip; - - /* unlock the device pointers */ - mutex_unlock(&chip->usb->dev_mutex); - -exit: - return retval; -} - -int rts51x_release(struct inode *inode, struct file *filp) -{ - struct rts51x_chip *chip; - - chip = (struct rts51x_chip *)filp->private_data; - if (chip == NULL) - return -ENODEV; - - /* Drop our reference to the host; the SCSI core will free it - * (and "chip" along with it) when the refcount becomes 0. */ - scsi_host_put(rts51x_to_host(chip)); - - return 0; -} - -ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count, - loff_t *f_pos) -{ - return 0; -} - -ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos) -{ - return 0; -} - -long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct rts51x_chip *chip; - struct sd_direct_cmnd cmnd; - struct sd_rsp rsp; - int retval = 0; - - chip = (struct rts51x_chip *)filp->private_data; - if (chip == NULL) - return -ENODEV; - - /* lock the device pointers */ - mutex_lock(&(chip->usb->dev_mutex)); - - switch (cmd) { - case RTS5139_IOC_SD_DIRECT: - retval = - copy_from_user((void *)&cmnd, (void __user *)arg, - sizeof(struct sd_direct_cmnd)); - if (retval) { - retval = -ENOMEM; - TRACE_GOTO(chip, exit); - } - retval = rts51x_sd_direct_cmnd(chip, &cmnd); - if (retval != STATUS_SUCCESS) { - retval = -EIO; - TRACE_GOTO(chip, exit); - } - break; - - case RTS5139_IOC_SD_GET_RSP: - retval = - copy_from_user(&rsp, (void __user *)arg, - sizeof(struct sd_rsp)); - if (retval) { - retval = -ENOMEM; - TRACE_GOTO(chip, exit); - } - retval = rts51x_sd_get_rsp(chip, &rsp); - if (retval != STATUS_SUCCESS) { - retval = -EIO; - TRACE_GOTO(chip, exit); - } - break; - - default: - break; - } - -exit: - /* unlock the device pointers */ - mutex_unlock(&chip->usb->dev_mutex); - - return retval; -} - -#endif diff --git a/drivers/staging/rts5139/rts51x_fop.h b/drivers/staging/rts5139/rts51x_fop.h deleted file mode 100644 index c691ee99720e..000000000000 --- a/drivers/staging/rts5139/rts51x_fop.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_FOP_H -#define __RTS51X_FOP_H - -#include "rts51x.h" - -#ifdef SUPPORT_FILE_OP - -#include -#include - -struct sd_direct_cmnd { - u8 cmnd[12]; - void __user *buf; - int buf_len; -}; - -struct sd_rsp { - void __user *rsp; - int rsp_len; -}; - -int rts51x_open(struct inode *inode, struct file *filp); -int rts51x_release(struct inode *inode, struct file *filp); -ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count, - loff_t *f_pos); -ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos); -long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); - -#endif - -#endif /* __RTS51X_FOP_H */ diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c deleted file mode 100644 index 75282fea38f7..000000000000 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ /dev/null @@ -1,2135 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "debug.h" -#include "rts51x.h" -#include "rts51x_chip.h" -#include "rts51x_scsi.h" -#include "rts51x_card.h" -#include "rts51x_transport.h" -#include "sd_cprm.h" -#include "ms_mg.h" -#include "trace.h" - -void rts51x_scsi_show_command(struct scsi_cmnd *srb) -{ - char *what = NULL; - int i, unknown_cmd = 0; - - switch (srb->cmnd[0]) { - case TEST_UNIT_READY: - what = (char *)"TEST_UNIT_READY"; - break; - case REZERO_UNIT: - what = (char *)"REZERO_UNIT"; - break; - case REQUEST_SENSE: - what = (char *)"REQUEST_SENSE"; - break; - case FORMAT_UNIT: - what = (char *)"FORMAT_UNIT"; - break; - case READ_BLOCK_LIMITS: - what = (char *)"READ_BLOCK_LIMITS"; - break; - case 0x07: - what = (char *)"REASSIGN_BLOCKS"; - break; - case READ_6: - what = (char *)"READ_6"; - break; - case WRITE_6: - what = (char *)"WRITE_6"; - break; - case SEEK_6: - what = (char *)"SEEK_6"; - break; - case READ_REVERSE: - what = (char *)"READ_REVERSE"; - break; - case WRITE_FILEMARKS: - what = (char *)"WRITE_FILEMARKS"; - break; - case SPACE: - what = (char *)"SPACE"; - break; - case INQUIRY: - what = (char *)"INQUIRY"; - break; - case RECOVER_BUFFERED_DATA: - what = (char *)"RECOVER_BUFFERED_DATA"; - break; - case MODE_SELECT: - what = (char *)"MODE_SELECT"; - break; - case RESERVE: - what = (char *)"RESERVE"; - break; - case RELEASE: - what = (char *)"RELEASE"; - break; - case COPY: - what = (char *)"COPY"; - break; - case ERASE: - what = (char *)"ERASE"; - break; - case MODE_SENSE: - what = (char *)"MODE_SENSE"; - break; - case START_STOP: - what = (char *)"START_STOP"; - break; - case RECEIVE_DIAGNOSTIC: - what = (char *)"RECEIVE_DIAGNOSTIC"; - break; - case SEND_DIAGNOSTIC: - what = (char *)"SEND_DIAGNOSTIC"; - break; - case ALLOW_MEDIUM_REMOVAL: - what = (char *)"ALLOW_MEDIUM_REMOVAL"; - break; - case SET_WINDOW: - what = (char *)"SET_WINDOW"; - break; - case READ_CAPACITY: - what = (char *)"READ_CAPACITY"; - break; - case READ_10: - what = (char *)"READ_10"; - break; - case WRITE_10: - what = (char *)"WRITE_10"; - break; - case SEEK_10: - what = (char *)"SEEK_10"; - break; - case WRITE_VERIFY: - what = (char *)"WRITE_VERIFY"; - break; - case VERIFY: - what = (char *)"VERIFY"; - break; - case SEARCH_HIGH: - what = (char *)"SEARCH_HIGH"; - break; - case SEARCH_EQUAL: - what = (char *)"SEARCH_EQUAL"; - break; - case SEARCH_LOW: - what = (char *)"SEARCH_LOW"; - break; - case SET_LIMITS: - what = (char *)"SET_LIMITS"; - break; - case READ_POSITION: - what = (char *)"READ_POSITION"; - break; - case SYNCHRONIZE_CACHE: - what = (char *)"SYNCHRONIZE_CACHE"; - break; - case LOCK_UNLOCK_CACHE: - what = (char *)"LOCK_UNLOCK_CACHE"; - break; - case READ_DEFECT_DATA: - what = (char *)"READ_DEFECT_DATA"; - break; - case MEDIUM_SCAN: - what = (char *)"MEDIUM_SCAN"; - break; - case COMPARE: - what = (char *)"COMPARE"; - break; - case COPY_VERIFY: - what = (char *)"COPY_VERIFY"; - break; - case WRITE_BUFFER: - what = (char *)"WRITE_BUFFER"; - break; - case READ_BUFFER: - what = (char *)"READ_BUFFER"; - break; - case UPDATE_BLOCK: - what = (char *)"UPDATE_BLOCK"; - break; - case READ_LONG: - what = (char *)"READ_LONG"; - break; - case WRITE_LONG: - what = (char *)"WRITE_LONG"; - break; - case CHANGE_DEFINITION: - what = (char *)"CHANGE_DEFINITION"; - break; - case WRITE_SAME: - what = (char *)"WRITE_SAME"; - break; - case GPCMD_READ_SUBCHANNEL: - what = (char *)"READ SUBCHANNEL"; - break; - case READ_TOC: - what = (char *)"READ_TOC"; - break; - case GPCMD_READ_HEADER: - what = (char *)"READ HEADER"; - break; - case GPCMD_PLAY_AUDIO_10: - what = (char *)"PLAY AUDIO (10)"; - break; - case GPCMD_PLAY_AUDIO_MSF: - what = (char *)"PLAY AUDIO MSF"; - break; - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - what = (char *)"GET EVENT/STATUS NOTIFICATION"; - break; - case GPCMD_PAUSE_RESUME: - what = (char *)"PAUSE/RESUME"; - break; - case LOG_SELECT: - what = (char *)"LOG_SELECT"; - break; - case LOG_SENSE: - what = (char *)"LOG_SENSE"; - break; - case GPCMD_STOP_PLAY_SCAN: - what = (char *)"STOP PLAY/SCAN"; - break; - case GPCMD_READ_DISC_INFO: - what = (char *)"READ DISC INFORMATION"; - break; - case GPCMD_READ_TRACK_RZONE_INFO: - what = (char *)"READ TRACK INFORMATION"; - break; - case GPCMD_RESERVE_RZONE_TRACK: - what = (char *)"RESERVE TRACK"; - break; - case GPCMD_SEND_OPC: - what = (char *)"SEND OPC"; - break; - case MODE_SELECT_10: - what = (char *)"MODE_SELECT_10"; - break; - case GPCMD_REPAIR_RZONE_TRACK: - what = (char *)"REPAIR TRACK"; - break; - case 0x59: - what = (char *)"READ MASTER CUE"; - break; - case MODE_SENSE_10: - what = (char *)"MODE_SENSE_10"; - break; - case GPCMD_CLOSE_TRACK: - what = (char *)"CLOSE TRACK/SESSION"; - break; - case 0x5C: - what = (char *)"READ BUFFER CAPACITY"; - break; - case 0x5D: - what = (char *)"SEND CUE SHEET"; - break; - case GPCMD_BLANK: - what = (char *)"BLANK"; - break; - case REPORT_LUNS: - what = (char *)"REPORT LUNS"; - break; - case MOVE_MEDIUM: - what = (char *)"MOVE_MEDIUM or PLAY AUDIO (12)"; - break; - case READ_12: - what = (char *)"READ_12"; - break; - case WRITE_12: - what = (char *)"WRITE_12"; - break; - case WRITE_VERIFY_12: - what = (char *)"WRITE_VERIFY_12"; - break; - case SEARCH_HIGH_12: - what = (char *)"SEARCH_HIGH_12"; - break; - case SEARCH_EQUAL_12: - what = (char *)"SEARCH_EQUAL_12"; - break; - case SEARCH_LOW_12: - what = (char *)"SEARCH_LOW_12"; - break; - case SEND_VOLUME_TAG: - what = (char *)"SEND_VOLUME_TAG"; - break; - case READ_ELEMENT_STATUS: - what = (char *)"READ_ELEMENT_STATUS"; - break; - case GPCMD_READ_CD_MSF: - what = (char *)"READ CD MSF"; - break; - case GPCMD_SCAN: - what = (char *)"SCAN"; - break; - case GPCMD_SET_SPEED: - what = (char *)"SET CD SPEED"; - break; - case GPCMD_MECHANISM_STATUS: - what = (char *)"MECHANISM STATUS"; - break; - case GPCMD_READ_CD: - what = (char *)"READ CD"; - break; - case 0xE1: - what = (char *)"WRITE CONTINUE"; - break; - case WRITE_LONG_2: - what = (char *)"WRITE_LONG_2"; - break; - case VENDOR_CMND: - what = (char *)"Realtek's vendor command"; - break; - default: - what = (char *)"(unknown command)"; - unknown_cmd = 1; - break; - } - - if (srb->cmnd[0] != TEST_UNIT_READY) - RTS51X_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); - if (unknown_cmd) { - RTS51X_DEBUGP(""); - for (i = 0; i < srb->cmd_len && i < 16; i++) - RTS51X_DEBUGPN(" %02x", srb->cmnd[i]); - RTS51X_DEBUGPN("\n"); - } -} - -void rts51x_set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) -{ - switch (sense_type) { - case SENSE_TYPE_MEDIA_CHANGE: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_NOT_PRESENT: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_PROTECT: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_ERR: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); - break; - - case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: - rts51x_set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, - ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); - break; - - case SENSE_TYPE_FORMAT_CMD_FAILED: - rts51x_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: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); - break; - - case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_WRITE_ERR: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); - break; -#endif - - case SENSE_TYPE_NO_SENSE: - default: - rts51x_set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); - break; - } -} - -void rts51x_set_sense_data(struct rts51x_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) >> 8; - sense->sns_key_info[2] = sns_key_info1 & 0x0f; - } -} - -static int test_unit_ready(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - rts51x_init_cards(chip); - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!check_lun_mc(chip, lun)) { - set_lun_mc(chip, lun); - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static unsigned char formatter_inquiry_str[20] = { - 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', - '-', 'M', 'G', /* Byte[47:49] */ - 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ - 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 rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 "; - char *inquiry_string; - unsigned char sendbytes; - unsigned char *buf; - u8 card = rts51x_get_lun_card(chip, lun); - int pro_formatter_flag = 0; - 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, - }; - - inquiry_string = inquiry_default; - - buf = vmalloc(scsi_bufflen(srb)); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - if (MS_FORMATTER_ENABLED(chip) && (get_lun2card(chip, lun) & MS_CARD)) { - if (!card || (card == MS_CARD)) - pro_formatter_flag = 1; - } - - 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, sendbytes - 8); - if (pro_formatter_flag) - buf[4] = 0x33; /* Additional Length */ - } 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); - - rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int start_stop_unit(struct scsi_cmnd *srb, struct rts51x_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)) - rts51x_eject_card(chip, lun); - return TRANSPORT_GOOD; - - case MAKE_MEDIUM_READY: - case LOAD_MEDIUM: - if (check_card_ready(chip, lun)) { - return TRANSPORT_GOOD; - } else { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - break; - } - - TRACE_RET(chip, TRANSPORT_ERROR); -} - -static int allow_medium_removal(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int prevent; - - prevent = srb->cmnd[4] & 0x1; - - scsi_set_resid(srb, 0); - - if (prevent) { - rts51x_set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - -static void ms_mode_sense(struct rts51x_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; - int support_format = 0; - 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 = 1; - buf[i++] = 0x40; - } else if (CHK_MSPRO(ms_card)) { - support_format = 1; - 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 rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - unsigned int dataSize; - int status; - int pro_formatter_flag; - unsigned char pageCode, *buf; - u8 card = rts51x_get_lun_card(chip, lun); - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - scsi_set_resid(srb, scsi_bufflen(srb)); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - pro_formatter_flag = 0; - dataSize = 8; - /* In Combo mode, device responses ModeSense command as a MS LUN - * when no card is inserted */ - if ((get_lun2card(chip, lun) & MS_CARD)) { - if (!card || (card == MS_CARD)) { - dataSize = 108; - if (chip->option.rts51x_mspro_formatter_enable) - pro_formatter_flag = 1; - } - } - - buf = kmalloc(dataSize, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - pageCode = srb->cmnd[2] & 0x3f; - - if ((pageCode == 0x3F) || (pageCode == 0x1C) || - (pageCode == 0x00) || (pro_formatter_flag && (pageCode == 0x20))) { - if (srb->cmnd[0] == MODE_SENSE) { - if ((pageCode == 0x3F) || (pageCode == 0x20)) { - ms_mode_sense(chip, srb->cmnd[0], lun, buf, - dataSize); - } else { - dataSize = 4; - buf[0] = 0x03; - buf[1] = 0x00; - if (check_card_wp(chip, lun)) - buf[2] = 0x80; - else - buf[3] = 0x00; - } - } else { - if ((pageCode == 0x3F) || (pageCode == 0x20)) { - ms_mode_sense(chip, srb->cmnd[0], lun, buf, - dataSize); - } else { - dataSize = 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 { - rts51x_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(scsi_bufflen(srb), dataSize); - rts51x_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - } - kfree(buf); - - return status; -} - -static int request_sense(struct scsi_cmnd *srb, struct rts51x_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 ((rts51x_get_lun_card(chip, lun) == MS_CARD) - && PRO_UNDER_FORMATTING(ms_card)) { - rts51x_mspro_format_sense(chip, lun); - } - - buf = vmalloc(scsi_bufflen(srb)); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - tmp = (unsigned char *)sense; - memcpy(buf, tmp, scsi_bufflen(srb)); - - rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - scsi_set_resid(srb, 0); - /* Reset Sense Data */ - rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - return TRANSPORT_GOOD; -} - -static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - int retval; - u32 start_sec; - u16 sec_cnt; - - if (!check_card_ready(chip, lun) || (chip->capacity[lun] == 0)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!check_lun_mc(chip, lun)) { - set_lun_mc(chip, lun); - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - 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]; - } 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 { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((start_sec > chip->capacity[lun]) || - ((start_sec + sec_cnt) > chip->capacity[lun])) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sec_cnt == 0) { - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - if ((srb->sc_data_direction == DMA_TO_DEVICE) - && check_card_wp(chip, lun)) { - RTS51X_DEBUGP("Write protected card!\n"); - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - retval = rts51x_card_rw(srb, chip, start_sec, sec_cnt); - if (retval != STATUS_SUCCESS) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } else { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - } - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int read_format_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - unsigned int buf_len; - u8 card = rts51x_get_lun_card(chip, lun); - int desc_cnt; - int i = 0; - - if (!check_card_ready(chip, lun)) { - if (!chip->option.rts51x_mspro_formatter_enable) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - buf[i++] = 0; - buf[i++] = 0; - buf[i++] = 0; - - /* Capacity List Length */ - if ((buf_len > 12) && chip->option.rts51x_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)) { - buf[i++] = (unsigned char)((chip->capacity[lun]) >> 24); - buf[i++] = (unsigned char)((chip->capacity[lun]) >> 16); - buf[i++] = (unsigned char)((chip->capacity[lun]) >> 8); - buf[i++] = (unsigned char)(chip->capacity[lun]); - - if (desc_cnt == 2) - /* Byte[8]: Descriptor Type: Formatted medium */ - buf[i++] = 2; - else - buf[i++] = 0; /* Byte[16] */ - } else { - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - - if (desc_cnt == 2) - /* Byte[8]: Descriptor Type: No medium */ - buf[i++] = 3; - else - buf[i++] = 0; /*Byte[16] */ - } - - buf[i++] = 0x00; - buf[i++] = 0x02; - buf[i++] = 0x00; - - desc_cnt--; - } - - buf_len = min(scsi_bufflen(srb), buf_len); - rts51x_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 rts51x_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!check_lun_mc(chip, lun)) { - set_lun_mc(chip, lun); - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - buf = kmalloc(8, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - buf[0] = (unsigned char)((chip->capacity[lun] - 1) >> 24); - buf[1] = (unsigned char)((chip->capacity[lun] - 1) >> 16); - buf[2] = (unsigned char)((chip->capacity[lun] - 1) >> 8); - buf[3] = (unsigned char)(chip->capacity[lun] - 1); - - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x02; - buf[7] = 0x00; - - rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); - kfree(buf); - - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int get_dev_status(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - unsigned int buf_len; - u8 status[32] = { 0 }; - - rts51x_pp_status(chip, lun, status, 32); - - buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(status)); - rts51x_set_xfer_buf(status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int read_status(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - u8 rts51x_status[16]; - unsigned int buf_len; - unsigned int lun = SCSI_LUN(srb); - - rts51x_read_status(chip, lun, rts51x_status, 16); - - buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(rts51x_status)); - rts51x_set_xfer_buf(rts51x_status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int read_mem(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - unsigned short addr, len, i; - int retval; - u8 *buf; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - addr = ((u16) srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16) srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xe000) { - RTS51X_DEBUGP("filter!addr=0x%x\n", addr); - return TRANSPORT_GOOD; - } - - buf = vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - for (i = 0; i < len; i++) { - retval = rts51x_ep0_read_register(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - rts51x_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 rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - unsigned short addr, len, i; - int retval; - u8 *buf; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - addr = ((u16) srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16) srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xe000) { - RTS51X_DEBUGP("filter!addr=0x%x\n", addr); - return TRANSPORT_GOOD; - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - buf = vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - rts51x_get_xfer_buf(buf, len, srb); - - for (i = 0; i < len; i++) { - retval = - rts51x_ep0_write_register(chip, addr + i, 0xFF, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - vfree(buf); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - return TRANSPORT_GOOD; -} - -static int get_sd_csd(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (rts51x_get_lun_card(chip, lun) != SD_CARD) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - rts51x_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -static int read_phy_register(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int retval; - u8 addr, len, i; - u8 *buf; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - addr = srb->cmnd[5]; - len = srb->cmnd[7]; - - if (len) { - buf = vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - for (i = 0; i < len; i++) { - retval = - rts51x_read_phy_register(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - rts51x_set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - len = min(scsi_bufflen(srb), (unsigned int)len); - rts51x_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 rts51x_chip *chip) -{ - int retval; - u8 addr, len, i; - u8 *buf; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - addr = srb->cmnd[5]; - len = srb->cmnd[7]; - - if (len) { - len = min(scsi_bufflen(srb), (unsigned int)len); - - buf = vmalloc(len); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rts51x_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - for (i = 0; i < len; i++) { - retval = - rts51x_write_phy_register(chip, addr + i, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - rts51x_set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int get_card_bus_width(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - u8 card, bus_width; - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - card = rts51x_get_lun_card(chip, lun); - if ((card == SD_CARD) || (card == MS_CARD)) { - bus_width = chip->card_bus_width[lun]; - } else { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - rts51x_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -#ifdef _MSG_TRACE -static int trace_msg_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned char *buf = NULL; - u8 clear; - unsigned int buf_len; - - buf_len = - 4 + - ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT); - - if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) { - rts51x_set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - clear = srb->cmnd[2]; - - buf = vmalloc(scsi_bufflen(srb)); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rts51x_trace_msg(chip, buf, clear); - - rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int retval = STATUS_SUCCESS; - unsigned int lun = SCSI_LUN(srb); - u8 cmd_type, mask, value, idx, mode, len; - u16 addr; - u32 timeout; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - rts51x_init_cmd(chip); - break; - - case ADD_BATCHCMD: - cmd_type = srb->cmnd[4]; - if (cmd_type > 2) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; - mask = srb->cmnd[7]; - value = srb->cmnd[8]; - rts51x_add_cmd(chip, cmd_type, addr, mask, value); - break; - - case SEND_BATCHCMD: - mode = srb->cmnd[4]; - len = srb->cmnd[5]; - timeout = - ((u32) srb->cmnd[6] << 24) | ((u32) srb-> - cmnd[7] << 16) | ((u32) srb-> - cmnd[8] << - 8) | ((u32) - srb-> - cmnd - [9]); - retval = rts51x_send_cmd(chip, mode, 1000); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if (mode & STAGE_R) { - retval = rts51x_get_rsp(chip, len, timeout); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - break; - - case GET_BATCHRSP: - idx = srb->cmnd[4]; - value = chip->rsp_buf[idx]; - if (scsi_bufflen(srb) < 1) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - rts51x_set_xfer_buf(&value, 1, srb); - scsi_set_resid(srb, 0); - break; - - default: - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - -static int suit_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int result; - - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - case ADD_BATCHCMD: - case SEND_BATCHCMD: - case GET_BATCHRSP: - result = rw_mem_cmd_buf(srb, chip); - break; - default: - result = TRANSPORT_ERROR; - } - - return result; -} - -static int app_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int result; - - switch (srb->cmnd[2]) { - case PP_READ10: - case PP_WRITE10: - result = read_write(srb, chip); - break; - - case SUIT_CMD: - result = suit_cmd(srb, chip); - break; - - case READ_PHY: - result = read_phy_register(srb, chip); - break; - - case WRITE_PHY: - result = write_phy_register(srb, chip); - break; - - case GET_DEV_STATUS: - result = get_dev_status(srb, chip); - break; - - default: - rts51x_set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return result; -} - -static int vendor_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int result = TRANSPORT_GOOD; - - 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 GET_BUS_WIDTH: - result = get_card_bus_width(srb, chip); - break; - - case GET_SD_CSD: - result = get_sd_csd(srb, chip); - break; - -#ifdef _MSG_TRACE - case TRACE_MSG: - result = trace_msg_cmd(srb, chip); - break; -#endif - - case SCSI_APP_CMD: - result = app_cmd(srb, chip); - break; - - default: - rts51x_set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return result; -} - -static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int retval, quick_format; - - if (rts51x_get_lun_card(chip, lun) != MS_CARD) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) - || (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) - || (srb->cmnd[7] != 0x74)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (srb->cmnd[8] & 0x01) - quick_format = 0; - else - quick_format = 1; - - if (!(chip->card_ready & MS_CARD)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (chip->card_wp & MS_CARD) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!CHK_MSPRO(ms_card)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - retval = rts51x_mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -#ifdef SUPPORT_PCGL_1P18 -static int get_ms_information(struct scsi_cmnd *srb, struct rts51x_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)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) || - (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) || - (srb->cmnd[7] != 0x44)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, 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)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (dev_info_id == 0x15) - buf_len = data_len = 0x3A; - else - buf_len = data_len = 0x6A; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, 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); - } - - rts51x_set_xfer_buf(buf, buf_len, srb); - - if (dev_info_id == 0x15) - scsi_set_resid(srb, scsi_bufflen(srb) - 0x3C); - else - scsi_set_resid(srb, scsi_bufflen(srb) - 0x6C); - - kfree(buf); - return STATUS_SUCCESS; -} -#endif - -static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rts51x_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_extention_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - int result; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - rts51x_sd_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((rts51x_get_lun_card(chip, lun) != SD_CARD)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - switch (srb->cmnd[0]) { - case SD_PASS_THRU_MODE: - result = rts51x_sd_pass_thru_mode(srb, chip); - break; - - case SD_EXECUTE_NO_DATA: - result = rts51x_sd_execute_no_data(srb, chip); - break; - - case SD_EXECUTE_READ: - result = rts51x_sd_execute_read_data(srb, chip); - break; - - case SD_EXECUTE_WRITE: - result = rts51x_sd_execute_write_data(srb, chip); - break; - - case SD_GET_RSP: - result = rts51x_sd_get_cmd_rsp(srb, chip); - break; - - case SD_HW_RST: - result = rts51x_sd_hw_rst(srb, chip); - break; - - default: - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return result; -} -#endif - -#ifdef SUPPORT_MAGIC_GATE -static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - rts51x_ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!CHK_MSPRO(ms_card)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - key_format = srb->cmnd[10] & 0x3F; - - switch (key_format) { - case KF_GET_LOC_EKB: - if ((scsi_bufflen(srb) == 0x41C) && - (srb->cmnd[8] == 0x04) && (srb->cmnd[9] == 0x1C)) { - retval = rts51x_mg_get_local_EKB(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_RSP_CHG: - if ((scsi_bufflen(srb) == 0x24) && - (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x24)) { - retval = rts51x_mg_get_rsp_chg(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, 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 = rts51x_mg_get_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - default: - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - rts51x_prepare_run(chip); - RTS51X_SET_STAT(chip, STAT_RUN); - - rts51x_ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if (check_card_wp(chip, lun)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!CHK_MSPRO(ms_card)) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - key_format = srb->cmnd[10] & 0x3F; - - switch (key_format) { - case KF_SET_LEAF_ID: - if ((scsi_bufflen(srb) == 0x0C) && - (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { - retval = rts51x_mg_set_leaf_id(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_CHG_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { - retval = rts51x_mg_chg(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_RSP_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { - retval = rts51x_mg_rsp(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, 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 = rts51x_mg_set_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - default: - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int result = TRANSPORT_GOOD; - - if ((rts51x_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 */ - rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16) (ms_card->progress)); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - switch (srb->cmnd[0]) { - case READ_10: - case WRITE_10: - case READ_6: - case WRITE_6: - result = read_write(srb, chip); - 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_extention_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: - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - result = TRANSPORT_FAILED; - } - - return result; -} - -/*********************************************************************** - * Host functions - ***********************************************************************/ - -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; -} - -int slave_configure(struct scsi_device *sdev) -{ - /* 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. */ - blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); - - /* 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 = 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...) seq_printf(m, ##args) - -static int write_info(struct Scsi_Host *host, char *buffer, int length) -{ - /* if someone is sending us data, just throw it away */ - return length; -} - -static int show_info(struct seq_file *m, struct Scsi_Host *host) -{ - /* print the controller name */ - SPRINTF(" Host scsi%d: %s\n", host->host_no, RTS51X_NAME); - - /* print product, vendor, and driver version strings */ - SPRINTF(" Vendor: Realtek Corp.\n"); - SPRINTF(" Product: RTS51xx USB Card Reader\n"); - SPRINTF(" Version: %s\n", DRIVER_VERSION); - return 0; -} - -/* queue a command */ -/* This is always called with scsi_lock(host) held */ -static int queuecommand_lck(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)) -{ - struct rts51x_chip *chip = host_to_rts51x(srb->device->host); - - /* check for state-transition errors */ - if (chip->srb != NULL) { - RTS51X_DEBUGP("Error in %s: chip->srb = %p\n", - __func__, chip->srb); - return SCSI_MLQUEUE_HOST_BUSY; - } - - /* fail the command if we are disconnecting */ - if (test_bit(FLIDX_DISCONNECTING, &chip->usb->dflags)) { - RTS51X_DEBUGP("Fail command during disconnect\n"); - srb->result = DID_NO_CONNECT << 16; - done(srb); - return 0; - } - - /* enqueue the command and wake up the control thread */ - srb->scsi_done = done; - chip->srb = srb; - complete(&chip->usb->cmnd_ready); - - return 0; -} - -DEF_SCSI_QCMD(queuecommand) -/*********************************************************************** - * Error handling functions - ***********************************************************************/ -/* Command timeout and abort */ -int command_abort(struct scsi_cmnd *srb) -{ - struct rts51x_chip *chip = host_to_rts51x(srb->device->host); - - RTS51X_DEBUGP("%s called\n", __func__); - - /* us->srb together with the TIMED_OUT, RESETTING, and ABORTING - * bits are protected by the host lock. */ - scsi_lock(rts51x_to_host(chip)); - - /* Is this command still active? */ - if (chip->srb != srb) { - scsi_unlock(rts51x_to_host(chip)); - RTS51X_DEBUGP("-- nothing to abort\n"); - return FAILED; - } - - /* Set the TIMED_OUT bit. Also set the ABORTING bit, but only if - * a device reset isn't already in progress (to avoid interfering - * with the reset). Note that we must retain the host lock while - * calling usb_stor_stop_transport(); otherwise it might interfere - * with an auto-reset that begins as soon as we release the lock. */ - set_bit(FLIDX_TIMED_OUT, &chip->usb->dflags); - if (!test_bit(FLIDX_RESETTING, &chip->usb->dflags)) { - set_bit(FLIDX_ABORTING, &chip->usb->dflags); - /* rts51x_stop_transport(us); */ - } - scsi_unlock(rts51x_to_host(chip)); - - /* Wait for the aborted command to finish */ - wait_for_completion(&chip->usb->notify); - return SUCCESS; -} - -/* This invokes the transport reset mechanism to reset the state of the - * device */ -static int device_reset(struct scsi_cmnd *srb) -{ - int result = 0; - - RTS51X_DEBUGP("%s called\n", __func__); - - return result < 0 ? FAILED : SUCCESS; -} - -/* Simulate a SCSI bus reset by resetting the device's USB port. */ -int bus_reset(struct scsi_cmnd *srb) -{ - int result = 0; - - RTS51X_DEBUGP("%s called\n", __func__); - - return result < 0 ? FAILED : SUCCESS; -} - -static const char *rts5139_info(struct Scsi_Host *host) -{ - return "SCSI emulation for RTS5139 USB card reader"; -} - -struct scsi_host_template rts51x_host_template = { - /* basic userland interface stuff */ - .name = RTS51X_NAME, - .proc_name = RTS51X_NAME, - .show_info = show_info, - .write_info = write_info, - .info = rts5139_info, - - /* command interface -- queued only */ - .queuecommand = queuecommand, - - /* error and abort handlers */ - .eh_abort_handler = command_abort, - .eh_device_reset_handler = device_reset, - .eh_bus_reset_handler = bus_reset, - - /* queue commands only, only one command per LUN */ - .can_queue = 1, - .cmd_per_lun = 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, - - /* merge commands... this seems to help performance, but - * periodically someone should test to see which setting is more - * optimal. - */ - .use_clustering = 1, - - /* emulated HBA */ - .emulated = 1, - - /* we do our own delay after a device or bus reset */ - .skip_settle_delay = 1, - - /* sysfs device attributes */ - /* .sdev_attrs = sysfs_device_attr_list, */ - - /* module management */ - .module = THIS_MODULE -}; - diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h deleted file mode 100644 index 1a0d70566186..000000000000 --- a/drivers/staging/rts5139/rts51x_scsi.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_SCSI_H -#define __RTS51X_SCSI_H - -#include -#include -#include -#include -#include -#include - -#include "rts51x_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_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 INIT_BATCHCMD 0x41 -#define ADD_BATCHCMD 0x42 -#define SEND_BATCHCMD 0x43 -#define GET_BATCHRSP 0x44 - -#ifdef SUPPORT_CPRM -/* 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 -#endif - -#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 - -struct rts51x_chip; - -/*----------------------------------- - 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 */ - -#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 */ - -void rts51x_scsi_show_command(struct scsi_cmnd *srb); -void rts51x_set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type); -void rts51x_set_sense_data(struct rts51x_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 rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip); - -struct Scsi_Host; -struct scsi_device; -struct scsi_cmnd; - -int slave_alloc(struct scsi_device *sdev); -int slave_configure(struct scsi_device *sdev); -int queuecommand(struct Scsi_Host *, struct scsi_cmnd *); -int command_abort(struct scsi_cmnd *srb); -int bus_reset(struct scsi_cmnd *srb); - -#endif /* __RTS51X_SCSI_H */ diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c deleted file mode 100644 index 0db1345df94e..000000000000 --- a/drivers/staging/rts5139/rts51x_transport.c +++ /dev/null @@ -1,738 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "debug.h" -#include "rts51x.h" -#include "rts51x_chip.h" -#include "rts51x_card.h" -#include "rts51x_scsi.h" -#include "rts51x_transport.h" -#include "trace.h" - -/*********************************************************************** - * Scatter-gather transfer buffer access routines - ***********************************************************************/ - -/* Copy a buffer of length buflen to/from the srb's transfer buffer. - * Update the **sgptr and *offset variables so that the next copy will - * pick up from where this one left off. - */ - -unsigned int rts51x_access_sglist(unsigned char *buffer, - unsigned int buflen, void *sglist, - void **sgptr, unsigned int *offset, - enum xfer_buf_dir dir) -{ - unsigned int cnt; - struct scatterlist *sg = (struct scatterlist *)*sgptr; - - /* We have to go through the list one entry - * at a time. Each s-g entry contains some number of pages, and - * each page has to be kmap()'ed separately. If the page is already - * in kernel-addressable memory then kmap() will return its address. - * If the page is not directly accessible -- such as a user buffer - * located in high memory -- then kmap() will map it to a temporary - * position in the kernel's virtual address space. - */ - - if (!sg) - sg = (struct scatterlist *)sglist; - - /* 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 **sgptr values for the next loop. - */ - cnt = 0; - while (cnt < buflen && sg) { - 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; - sg = sg_next(sg); - } - - /* Transfer the data for all the pages in this - * s-g entry. For each page: call kmap(), do the - * transfer, and call kunmap() immediately after. */ - while (sglen > 0) { - unsigned int plen = min(sglen, (unsigned int) - PAGE_SIZE - poff); - unsigned char *ptr = kmap(page); - - if (dir == TO_XFER_BUF) - memcpy(ptr + poff, buffer + cnt, plen); - else - memcpy(buffer + cnt, ptr + poff, plen); - kunmap(page); - - /* Start at the beginning of the next page */ - poff = 0; - ++page; - cnt += plen; - sglen -= plen; - } - } - *sgptr = sg; - - /* Return the amount actually transferred */ - return cnt; -} - -static unsigned int rts51x_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb, - struct scatterlist **sgptr, - unsigned int *offset, enum xfer_buf_dir dir) -{ - return rts51x_access_sglist(buffer, buflen, (void *)scsi_sglist(srb), - (void **)sgptr, offset, dir); -} - -/* Store the contents of buffer into srb's transfer buffer and set the - * SCSI residue. - */ -void rts51x_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int offset = 0; - struct scatterlist *sg = NULL; - - buflen = min(buflen, scsi_bufflen(srb)); - buflen = rts51x_access_xfer_buf(buffer, buflen, srb, &sg, &offset, - TO_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - -void rts51x_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int offset = 0; - struct scatterlist *sg = NULL; - - buflen = min(buflen, scsi_bufflen(srb)); - buflen = rts51x_access_xfer_buf(buffer, buflen, srb, &sg, &offset, - FROM_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - -/* This is the completion handler which will wake us up when an URB - * completes. - */ -static void urb_done_completion(struct urb *urb) -{ - struct completion *urb_done_ptr = urb->context; - - if (urb_done_ptr) - complete(urb_done_ptr); -} - -/* This is the common part of the URB message submission code - * - * All URBs from the driver involved in handling a queued scsi - * command _must_ pass through this function (or something like it) for the - * abort mechanisms to work properly. - */ -static int rts51x_msg_common(struct rts51x_chip *chip, struct urb *urb, - int timeout) -{ - struct rts51x_usb *rts51x = chip->usb; - struct completion urb_done; - long timeleft; - int status; - - /* don't submit URBs during abort processing */ - if (test_bit(FLIDX_ABORTING, &rts51x->dflags)) - TRACE_RET(chip, -EIO); - - /* set up data structures for the wakeup system */ - init_completion(&urb_done); - - /* fill the common fields in the URB */ - urb->context = &urb_done; - urb->actual_length = 0; - urb->error_count = 0; - urb->status = 0; - - /* we assume that if transfer_buffer isn't us->iobuf then it - * hasn't been mapped for DMA. Yes, this is clunky, but it's - * easier than always having the caller tell us whether the - * transfer buffer has already been mapped. */ - urb->transfer_flags = URB_NO_SETUP_DMA_MAP; - if (urb->transfer_buffer == rts51x->iobuf) { - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - urb->transfer_dma = rts51x->iobuf_dma; - } - urb->setup_dma = rts51x->cr_dma; - - /* submit the URB */ - status = usb_submit_urb(urb, GFP_NOIO); - if (status) { - /* something went wrong */ - TRACE_RET(chip, status); - } - - /* since the URB has been submitted successfully, it's now okay - * to cancel it */ - set_bit(FLIDX_URB_ACTIVE, &rts51x->dflags); - - /* did an abort occur during the submission? */ - if (test_bit(FLIDX_ABORTING, &rts51x->dflags)) { - - /* cancel the URB, if it hasn't been cancelled already */ - if (test_and_clear_bit(FLIDX_URB_ACTIVE, &rts51x->dflags)) { - RTS51X_DEBUGP("-- cancelling URB\n"); - usb_unlink_urb(urb); - } - } - - /* wait for the completion of the URB */ - timeleft = - wait_for_completion_interruptible_timeout(&urb_done, - (timeout * HZ / - 1000) ? : - MAX_SCHEDULE_TIMEOUT); - - clear_bit(FLIDX_URB_ACTIVE, &rts51x->dflags); - - if (timeleft <= 0) { - RTS51X_DEBUGP("%s -- cancelling URB\n", - timeleft == 0 ? "Timeout" : "Signal"); - usb_kill_urb(urb); - if (timeleft == 0) - status = -ETIMEDOUT; - else - status = -EINTR; - } else { - status = urb->status; - } - - return status; -} - -static int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe); - -/* - * Interpret the results of a URB transfer - */ -static int interpret_urb_result(struct rts51x_chip *chip, unsigned int pipe, - unsigned int length, int result, - unsigned int partial) -{ - int retval = STATUS_SUCCESS; - - /* RTS51X_DEBUGP("Status code %d; transferred %u/%u\n", - result, partial, length); */ - switch (result) { - /* no error code; did we send all the data? */ - case 0: - if (partial != length) { - RTS51X_DEBUGP("-- short transfer\n"); - TRACE_RET(chip, STATUS_TRANS_SHORT); - } - /* RTS51X_DEBUGP("-- transfer complete\n"); */ - return STATUS_SUCCESS; - /* stalled */ - case -EPIPE: - /* for control endpoints, (used by CB[I]) a stall indicates - * a failed command */ - if (usb_pipecontrol(pipe)) { - RTS51X_DEBUGP("-- stall on control pipe\n"); - TRACE_RET(chip, STATUS_STALLED); - } - /* for other sorts of endpoint, clear the stall */ - RTS51X_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); - if (rts51x_clear_halt(chip, pipe) < 0) - TRACE_RET(chip, STATUS_ERROR); - retval = STATUS_STALLED; - TRACE_GOTO(chip, Exit); - - /* babble - the device tried to send more than - * we wanted to read */ - case -EOVERFLOW: - RTS51X_DEBUGP("-- babble\n"); - retval = STATUS_TRANS_LONG; - TRACE_GOTO(chip, Exit); - - /* the transfer was cancelled by abort, - * disconnect, or timeout */ - case -ECONNRESET: - RTS51X_DEBUGP("-- transfer cancelled\n"); - retval = STATUS_ERROR; - TRACE_GOTO(chip, Exit); - - /* short scatter-gather read transfer */ - case -EREMOTEIO: - RTS51X_DEBUGP("-- short read transfer\n"); - retval = STATUS_TRANS_SHORT; - TRACE_GOTO(chip, Exit); - - /* abort or disconnect in progress */ - case -EIO: - RTS51X_DEBUGP("-- abort or disconnect in progress\n"); - retval = STATUS_ERROR; - TRACE_GOTO(chip, Exit); - - case -ETIMEDOUT: - RTS51X_DEBUGP("-- time out\n"); - retval = STATUS_TIMEDOUT; - TRACE_GOTO(chip, Exit); - - /* the catch-all error case */ - default: - RTS51X_DEBUGP("-- unknown error\n"); - retval = STATUS_ERROR; - TRACE_GOTO(chip, Exit); - } - -Exit: - if ((retval != STATUS_SUCCESS) && !usb_pipecontrol(pipe)) - rts51x_clear_hw_error(chip); - - return retval; -} - -int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, - u8 request, u8 requesttype, u16 value, u16 index, - void *data, u16 size, int timeout) -{ - struct rts51x_usb *rts51x = chip->usb; - int result; - - RTS51X_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n", - __func__, request, requesttype, value, index, size); - - /* fill in the devrequest structure */ - rts51x->cr->bRequestType = requesttype; - rts51x->cr->bRequest = request; - rts51x->cr->wValue = cpu_to_le16(value); - rts51x->cr->wIndex = cpu_to_le16(index); - rts51x->cr->wLength = cpu_to_le16(size); - - /* fill and submit the URB */ - usb_fill_control_urb(rts51x->current_urb, rts51x->pusb_dev, pipe, - (unsigned char *)rts51x->cr, data, size, - urb_done_completion, NULL); - result = rts51x_msg_common(chip, rts51x->current_urb, timeout); - - return interpret_urb_result(chip, pipe, size, result, - rts51x->current_urb->actual_length); -} - -static int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) -{ - int result; - int endp = usb_pipeendpoint(pipe); - - if (usb_pipein(pipe)) - endp |= USB_DIR_IN; - - result = rts51x_ctrl_transfer(chip, SND_CTRL_PIPE(chip), - USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, - USB_ENDPOINT_HALT, endp, NULL, 0, 3000); - if (result != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - usb_reset_endpoint(chip->usb->pusb_dev, endp); - - return STATUS_SUCCESS; -} - -static void rts51x_sg_clean(struct usb_sg_request *io) -{ - if (io->urbs) { - while (io->entries--) - usb_free_urb(io->urbs[io->entries]); - kfree(io->urbs); - io->urbs = NULL; - } - io->dev = NULL; -} - -static int rts51x_sg_init(struct usb_sg_request *io, struct usb_device *dev, - unsigned pipe, unsigned period, struct scatterlist *sg, - int nents, size_t length, gfp_t mem_flags) -{ - return usb_sg_init(io, dev, pipe, period, sg, nents, length, mem_flags); -} - -static int rts51x_sg_wait(struct usb_sg_request *io, int timeout) -{ - long timeleft; - int i; - int entries = io->entries; - - /* queue the urbs. */ - spin_lock_irq(&io->lock); - i = 0; - while (i < entries && !io->status) { - int retval; - - io->urbs[i]->dev = io->dev; - retval = usb_submit_urb(io->urbs[i], GFP_ATOMIC); - - /* after we submit, let completions or cancelations fire; - * we handshake using io->status. - */ - spin_unlock_irq(&io->lock); - switch (retval) { - /* maybe the retry will recover */ - case -ENXIO: /* hc didn't queue this one */ - case -EAGAIN: - case -ENOMEM: - io->urbs[i]->dev = NULL; - retval = 0; - yield(); - break; - - /* no error? continue immediately. - * - * NOTE: to work better with UHCI (4K I/O buffer may - * need 3K of TDs) it may be good to limit how many - * URBs are queued at once; N milliseconds? - */ - case 0: - ++i; - cpu_relax(); - break; - - /* fail any uncompleted urbs */ - default: - io->urbs[i]->dev = NULL; - io->urbs[i]->status = retval; - dev_dbg(&io->dev->dev, "%s, submit --> %d\n", - __func__, retval); - usb_sg_cancel(io); - } - spin_lock_irq(&io->lock); - if (retval && (io->status == 0 || io->status == -ECONNRESET)) - io->status = retval; - } - io->count -= entries - i; - if (io->count == 0) - complete(&io->complete); - spin_unlock_irq(&io->lock); - - timeleft = - wait_for_completion_interruptible_timeout(&io->complete, - (timeout * HZ / - 1000) ? : - MAX_SCHEDULE_TIMEOUT); - if (timeleft <= 0) { - RTS51X_DEBUGP("%s -- cancelling SG request\n", - timeleft == 0 ? "Timeout" : "Signal"); - usb_sg_cancel(io); - if (timeleft == 0) - io->status = -ETIMEDOUT; - else - io->status = -EINTR; - } - - rts51x_sg_clean(io); - return io->status; -} - -/* - * Transfer a scatter-gather list via bulk transfer - * - * This function does basically the same thing as usb_stor_bulk_transfer_buf() - * above, but it uses the usbcore scatter-gather library. - */ -static int rts51x_bulk_transfer_sglist(struct rts51x_chip *chip, - unsigned int pipe, - struct scatterlist *sg, int num_sg, - unsigned int length, - unsigned int *act_len, int timeout) -{ - int result; - - /* don't submit s-g requests during abort processing */ - if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) - TRACE_RET(chip, STATUS_ERROR); - - /* initialize the scatter-gather request block */ - RTS51X_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__, - length, num_sg); - result = - rts51x_sg_init(&chip->usb->current_sg, chip->usb->pusb_dev, pipe, 0, - sg, num_sg, length, GFP_NOIO); - if (result) { - RTS51X_DEBUGP("rts51x_sg_init returned %d\n", result); - TRACE_RET(chip, STATUS_ERROR); - } - - /* since the block has been initialized successfully, it's now - * okay to cancel it */ - set_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); - - /* did an abort occur during the submission? */ - if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) { - - /* cancel the request, if it hasn't been cancelled already */ - if (test_and_clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags)) { - RTS51X_DEBUGP("-- cancelling sg request\n"); - usb_sg_cancel(&chip->usb->current_sg); - } - } - - /* wait for the completion of the transfer */ - result = rts51x_sg_wait(&chip->usb->current_sg, timeout); - - clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); - - /* result = us->current_sg.status; */ - if (act_len) - *act_len = chip->usb->current_sg.bytes; - return interpret_urb_result(chip, pipe, length, result, - chip->usb->current_sg.bytes); -} - -static int rts51x_bulk_transfer_buf(struct rts51x_chip *chip, - unsigned int pipe, - void *buf, unsigned int length, - unsigned int *act_len, int timeout) -{ - int result; - - /* fill and submit the URB */ - usb_fill_bulk_urb(chip->usb->current_urb, chip->usb->pusb_dev, pipe, - buf, length, urb_done_completion, NULL); - result = rts51x_msg_common(chip, chip->usb->current_urb, timeout); - - /* store the actual length of the data transferred */ - if (act_len) - *act_len = chip->usb->current_urb->actual_length; - return interpret_urb_result(chip, pipe, length, result, - chip->usb->current_urb->actual_length); -} - -int rts51x_transfer_data(struct rts51x_chip *chip, unsigned int pipe, - void *buf, unsigned int len, int use_sg, - unsigned int *act_len, int timeout) -{ - int result; - - if (timeout < 600) - timeout = 600; - - if (use_sg) { - result = - rts51x_bulk_transfer_sglist(chip, pipe, - (struct scatterlist *)buf, - use_sg, len, act_len, timeout); - } else { - result = - rts51x_bulk_transfer_buf(chip, pipe, buf, len, act_len, - timeout); - } - - return result; -} - -int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, - void *buf, void **ptr, unsigned int *offset, - unsigned int len, int use_sg, - unsigned int *act_len, int timeout) -{ - int result; - - if (timeout < 600) - timeout = 600; - - if (use_sg) { - void *tmp_buf = kmalloc(len, GFP_KERNEL); - if (!tmp_buf) - TRACE_RET(chip, STATUS_NOMEM); - - if (usb_pipeout(pipe)) { - rts51x_access_sglist(tmp_buf, len, buf, ptr, offset, - FROM_XFER_BUF); - } - result = - rts51x_bulk_transfer_buf(chip, pipe, tmp_buf, len, act_len, - timeout); - if (result == STATUS_SUCCESS) { - if (usb_pipein(pipe)) { - rts51x_access_sglist(tmp_buf, len, buf, ptr, - offset, TO_XFER_BUF); - } - } - - kfree(tmp_buf); - } else { - unsigned int step = 0; - if (offset) - step = *offset; - result = - rts51x_bulk_transfer_buf(chip, pipe, buf + step, len, - act_len, timeout); - if (act_len) - step += *act_len; - else - step += len; - if (offset) - *offset = step; - } - - return result; -} - -int rts51x_get_epc_status(struct rts51x_chip *chip, u16 *status) -{ - unsigned int pipe = RCV_INTR_PIPE(chip); - struct usb_host_endpoint *ep; - struct completion urb_done; - int result; - - if (!status) - TRACE_RET(chip, STATUS_ERROR); - - /* set up data structures for the wakeup system */ - init_completion(&urb_done); - - ep = chip->usb->pusb_dev->ep_in[usb_pipeendpoint(pipe)]; - - /* fill and submit the URB */ - /* Set interval to 10 here to match the endpoint descriptor, - * the polling interval is controlled by the polling thread */ - usb_fill_int_urb(chip->usb->intr_urb, chip->usb->pusb_dev, pipe, - status, 2, urb_done_completion, &urb_done, 10); - - result = rts51x_msg_common(chip, chip->usb->intr_urb, 100); - - return interpret_urb_result(chip, pipe, 2, result, - chip->usb->intr_urb->actual_length); -} - -void rts51x_invoke_transport(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int result; - -#ifdef CONFIG_PM - static const u8 media_not_present[] = { - 0x70, 0, 0x02, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0x3A, 0, 0, 0, 0, 0 - }; - static const u8 invalid_cmd_field[] = { - 0x70, 0, 0x05, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0x24, 0, 0, 0, 0, 0 - }; - - if (chip->option.ss_en) { - if (srb->cmnd[0] == TEST_UNIT_READY) { - if (RTS51X_CHK_STAT(chip, STAT_SS)) { - if (check_fake_card_ready(chip, - SCSI_LUN(srb))) { - srb->result = SAM_STAT_GOOD; - } else { - srb->result = SAM_STAT_CHECK_CONDITION; - memcpy(srb->sense_buffer, - media_not_present, SENSE_SIZE); - } - return; - } - } else if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { - if (RTS51X_CHK_STAT(chip, STAT_SS)) { - int prevent = srb->cmnd[4] & 0x1; - - if (prevent) { - srb->result = SAM_STAT_CHECK_CONDITION; - memcpy(srb->sense_buffer, - invalid_cmd_field, SENSE_SIZE); - } else { - srb->result = SAM_STAT_GOOD; - } - return; - } - } else { - if (RTS51X_CHK_STAT(chip, STAT_SS) - || RTS51X_CHK_STAT(chip, STAT_SS_PRE)) { - /* Wake up device */ - RTS51X_DEBUGP("Try to wake up device\n"); - chip->resume_from_scsi = 1; - - rts51x_try_to_exit_ss(chip); - - if (RTS51X_CHK_STAT(chip, STAT_SS)) { - wait_timeout(3000); - - rts51x_init_chip(chip); - rts51x_init_cards(chip); - } - } - } - } -#endif - - result = rts51x_scsi_handler(srb, chip); - - /* if there is a transport error, reset and don't auto-sense */ - if (result == TRANSPORT_ERROR) { - RTS51X_DEBUGP("-- 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; - - /* Error and abort processing: try to resynchronize with the device - * by issuing a port reset. If that fails, try a class-specific - * device reset. */ -Handle_Errors: - return; -} diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h deleted file mode 100644 index 024f115540a6..000000000000 --- a/drivers/staging/rts5139/rts51x_transport.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_TRANSPORT_H -#define __RTS51X_TRANSPORT_H - -#include - -#include "rts51x.h" -#include "rts51x_chip.h" - -#if 1 /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) */ -#define URB_NO_SETUP_DMA_MAP 0 -#endif - -unsigned int rts51x_access_sglist(unsigned char *buffer, - unsigned int buflen, void *sglist, - void **sgptr, unsigned int *offset, - enum xfer_buf_dir dir); -void rts51x_set_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb); -void rts51x_get_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb); - -int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, - u8 request, u8 requesttype, u16 value, u16 index, - void *data, u16 size, int timeout); -int rts51x_transfer_data(struct rts51x_chip *chip, unsigned int pipe, - void *buf, unsigned int len, int use_sg, - unsigned int *act_len, int timeout); -int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, - void *buf, void **ptr, unsigned int *offset, - unsigned int len, int use_sg, - unsigned int *act_len, int timeout); - -#ifndef POLLING_IN_THREAD -int rts51x_start_epc_transfer(struct rts51x_chip *chip); -void rts51x_cancel_epc_transfer(struct rts51x_chip *chip); -#endif - -int rts51x_get_epc_status(struct rts51x_chip *chip, u16 *status); -void rts51x_invoke_transport(struct scsi_cmnd *srb, struct rts51x_chip *chip); - -#endif /* __RTS51X_TRANSPORT_H */ diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c deleted file mode 100644 index da5a9b8fb69c..000000000000 --- a/drivers/staging/rts5139/sd.c +++ /dev/null @@ -1,3274 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include - -#include "debug.h" -#include "trace.h" -#include "rts51x.h" -#include "rts51x_transport.h" -#include "rts51x_scsi.h" -#include "rts51x_card.h" -#include "sd.h" - -static inline void sd_set_reset_fail(struct rts51x_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &(chip->sd_card); - - sd_card->sd_reset_fail |= err_code; -} - -static inline void sd_clear_reset_fail(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - sd_card->sd_reset_fail = 0; -} - -static inline int sd_check_reset_fail(struct rts51x_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &(chip->sd_card); - - return sd_card->sd_reset_fail & err_code; -} - -static inline void sd_set_err_code(struct rts51x_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 rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - sd_card->err_code = 0; -} - -static inline int sd_check_err_code(struct rts51x_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &(chip->sd_card); - - return sd_card->err_code & err_code; -} - -static int sd_parse_err_code(struct rts51x_chip *chip) -{ - TRACE_RET(chip, STATUS_FAIL); -} - -int sd_check_data0_status(struct rts51x_chip *chip) -{ - int retval; - u8 stat; - - retval = rts51x_ep0_read_register(chip, SD_BUS_STAT, &stat); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (!(stat & SD_DAT0_STATUS)) { - sd_set_err_code(chip, SD_BUSY); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_send_cmd_get_rsp(struct rts51x_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 = 50; - u16 reg_addr; - u8 buf[17], stat; - int len = 2; - int rty_cnt = 0; - - sd_clr_err_code(chip); - - RTS51X_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8) (arg >> 24)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8) (arg >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8) (arg >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_CMD_RSP | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, - SD_TRANSFER_END | SD_STAT_IDLE, - SD_TRANSFER_END | SD_STAT_IDLE); - - rts51x_add_cmd(chip, READ_REG_CMD, SD_STAT1, 0, 0); - - if (CHECK_USB(chip, USB_20)) { - if (rsp_type == SD_RSP_TYPE_R2) { - /* Read data from ping-pong buffer */ - for (reg_addr = PPBUF_BASE2; - reg_addr < PPBUF_BASE2 + 16; reg_addr++) { - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, - 0); - } - len = 18; - } else if (rsp_type != SD_RSP_TYPE_R0) { - /* Read data from SD_CMDx registers */ - for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; - reg_addr++) { - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, - 0); - } - len = 7; - } else { - len = 2; - } - } else { - len = 2; - } - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, len, timeout); - - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - u8 val; - - rts51x_ep0_read_register(chip, SD_STAT1, &val); - RTS51X_DEBUGP("SD_STAT1: 0x%x\n", val); - - rts51x_ep0_read_register(chip, SD_STAT2, &val); - RTS51X_DEBUGP("SD_STAT2: 0x%x\n", val); - - if (val & SD_RSP_80CLK_TIMEOUT) - sd_set_err_code(chip, SD_RSP_TIMEOUT); - - rts51x_ep0_read_register(chip, SD_BUS_STAT, &val); - RTS51X_DEBUGP("SD_BUS_STAT: 0x%x\n", val); - - if (retval == STATUS_TIMEDOUT) { - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - sd_set_err_code(chip, SD_TO_ERR); - } - } - rts51x_clear_sd_error(chip); - - TRACE_RET(chip, STATUS_FAIL); - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - if (CHECK_USB(chip, USB_20)) { - rts51x_read_rsp_buf(chip, 2, buf, len - 2); - } else { - if (rsp_type == SD_RSP_TYPE_R2) { - reg_addr = PPBUF_BASE2; - len = 16; - } else { - reg_addr = SD_CMD0; - len = 5; - } - retval = rts51x_seq_read_register(chip, reg_addr, - (unsigned short)len, buf); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - stat = chip->rsp_buf[1]; - - /* Check (Start,Transmission) bit of Response */ - if ((buf[0] & 0xC0) != 0) { - sd_set_err_code(chip, SD_STS_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - /* Check CRC7 */ - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (stat & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) { - sd_set_err_code(chip, SD_CRC_ERR); - TRACE_RET(chip, 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); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - /* Check Status */ - 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 (buf[1] & 0x80) - TRACE_RET(chip, STATUS_FAIL); - } - if (buf[1] & 0x7F) { - RTS51X_DEBUGP("buf[1]: 0x%02x\n", buf[1]); - TRACE_RET(chip, STATUS_FAIL); - } - if (buf[2] & 0xFF) { - RTS51X_DEBUGP("buf[2]: 0x%02x\n", buf[2]); - TRACE_RET(chip, STATUS_FAIL); - } - if (buf[3] & 0x80) { - RTS51X_DEBUGP("buf[3]: 0x%02x\n", buf[3]); - TRACE_RET(chip, STATUS_FAIL); - } - if (buf[3] & 0x01) { - /* Get "READY_FOR_DATA" bit */ - sd_card->sd_data_buf_ready = 1; - } else { - sd_card->sd_data_buf_ready = 0; - } - } - } - - if (rsp && rsp_len) - memcpy(rsp, buf, rsp_len); - - return STATUS_SUCCESS; -} - -static inline void sd_print_debug_reg(struct rts51x_chip *chip) -{ -#ifdef CONFIG_RTS5139_DEBUG - u8 val = 0; - - rts51x_ep0_read_register(chip, SD_STAT1, &val); - RTS51X_DEBUGP("SD_STAT1: 0x%x\n", val); - rts51x_ep0_read_register(chip, SD_STAT2, &val); - RTS51X_DEBUGP("SD_STAT2: 0x%x\n", val); - rts51x_ep0_read_register(chip, SD_BUS_STAT, &val); - RTS51X_DEBUGP("SD_BUS_STAT: 0x%x\n", val); -#endif -} - -int sd_read_data(struct rts51x_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 read data more than one page */ - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - - if (cmd_len) { - RTS51X_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, - cmd[i]); - } - } - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8) byte_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, - (u8) (byte_cnt >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, (u8) blk_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, - (u8) (blk_cnt >> 8)); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); - - rts51x_add_cmd(chip, WRITE_REG_CMD, 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) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - } - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - trans_mode | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 1, timeout); - - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - sd_print_debug_reg(chip); - if (retval == STATUS_TIMEDOUT) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - TRACE_RET(chip, STATUS_FAIL); - } - - if (buf && buf_len) { - retval = rts51x_read_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int sd_write_data(struct rts51x_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; - - /* This function can't write data more than one page */ - if (buf_len > 512) - TRACE_RET(chip, STATUS_FAIL); - - if (buf && buf_len) { - retval = rts51x_write_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - rts51x_init_cmd(chip); - - if (cmd_len) { - RTS51X_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, - cmd[i]); - } - } - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8) byte_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, - (u8) (byte_cnt >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, (u8) blk_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, - (u8) (blk_cnt >> 8)); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); - - if (cmd_len) { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); - - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | - SD_RSP_LEN_6); - } - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - trans_mode | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 1, timeout); - - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - sd_print_debug_reg(chip); - - if (retval == STATUS_TIMEDOUT) - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_check_csd(struct rts51x_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 (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - sd_set_reset_fail(chip, SD_RESET_FAIL); - TRACE_RET(chip, 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) - TRACE_RET(chip, STATUS_FAIL); - memcpy(sd_card->raw_csd, rsp + 1, 15); - /* Get CRC7 */ - RTS51X_READ_REG(chip, SD_CMD5, sd_card->raw_csd + 15); - - RTS51X_DEBUGP("CSD Response:\n"); - RTS51X_DUMP(rsp, 16); - - /* Get CSD Version */ - csd_ver = (rsp[1] & 0xc0) >> 6; - RTS51X_DEBUGP("csd_ver = %d\n", csd_ver); - - trans_speed = rsp[4]; - if ((trans_speed & 0x07) == 0x02) { /* 10Mbits/s */ - if ((trans_speed & 0xf8) >= 0x30) { /* >25Mbits/s */ - if (chip->asic_code) - sd_card->sd_clock = 46; - else - sd_card->sd_clock = CLK_50; - } else if ((trans_speed & 0xf8) == 0x28) { /* 20Mbits/s */ - if (chip->asic_code) - sd_card->sd_clock = 39; - else - sd_card->sd_clock = CLK_40; - } else if ((trans_speed & 0xf8) == 0x20) { /* 15Mbits/s */ - if (chip->asic_code) - sd_card->sd_clock = 29; - else - sd_card->sd_clock = CLK_30; - } else if ((trans_speed & 0xf8) >= 0x10) { /* 12Mbits/s */ - if (chip->asic_code) - sd_card->sd_clock = 23; - else - sd_card->sd_clock = CLK_20; - } else if ((trans_speed & 0x08) >= 0x08) { /* 10Mbits/s */ - if (chip->asic_code) - sd_card->sd_clock = 19; - else - sd_card->sd_clock = CLK_20; - } /*else { */ - /*If this ,then slow card will use 30M clock */ - /* TRACE_RET(chip, STATUS_FAIL); */ - /* } */ - } - /*else { - TRACE_RET(chip, STATUS_FAIL); - } */ - if (CHK_MMC_SECTOR_MODE(sd_card)) { - sd_card->capacity = 0; - } else { - /* For High-Capacity Card, CSD_STRUCTURE always be "0x1" */ - if ((!CHK_SD_HCXC(sd_card)) || (csd_ver == 0)) { - /* Calculate total sector according to C_SIZE, - * C_SIZE_MULT & READ_BL_LEN */ - u8 blk_size, c_size_mult; - u16 c_size; - /* Get READ_BL_LEN */ - blk_size = rsp[6] & 0x0F; - /* Get C_SIZE */ - c_size = ((u16) (rsp[7] & 0x03) << 10) - + ((u16) rsp[8] << 2) - + ((u16) (rsp[9] & 0xC0) >> 6); - /* Get C_SIZE_MUL */ - c_size_mult = (u8) ((rsp[10] & 0x03) << 1); - c_size_mult += (rsp[11] & 0x80) >> 7; - /* Calculate total Capacity */ - sd_card->capacity = - (((u32) (c_size + 1)) * - (1 << (c_size_mult + 2))) << (blk_size - 9); - } else { - /* High Capacity Card and Use CSD2.0 Version */ - u32 total_sector = 0; - total_sector = (((u32) rsp[8] & 0x3f) << 16) | - ((u32) rsp[9] << 8) | (u32) rsp[10]; - /* Total Capacity= (C_SIZE+1) * - * 512K Byte = (C_SIZE+1)K Sector,1K = 1024 Bytes */ - sd_card->capacity = (total_sector + 1) << 10; - } - } - - /* We need check Write-Protected Status by Field PERM WP or TEMP WP */ - if (check_wp) { - if (rsp[15] & 0x30) - chip->card_wp |= SD_CARD; - RTS51X_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]); - } - - return STATUS_SUCCESS; -} - -static int sd_set_sample_push_timing(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - rts51x_init_cmd(chip); - - if (CHK_SD_SDR104(sd_card) || CHK_SD_SDR50(sd_card)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, - 0x0C | SD_ASYNC_FIFO_RST, - SD_30_MODE | SD_ASYNC_FIFO_RST); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, - CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); - } else if (CHK_SD_DDR50(sd_card) || CHK_MMC_DDR52(sd_card)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, - 0x0C | SD_ASYNC_FIFO_RST, - SD_DDR_MODE | SD_ASYNC_FIFO_RST); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, - CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PUSH_POINT_CTL, - DDR_VAR_TX_CMD_DAT, DDR_VAR_TX_CMD_DAT); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, - DDR_VAR_RX_DAT | DDR_VAR_RX_CMD, - DDR_VAR_RX_DAT | DDR_VAR_RX_CMD); - } else { - u8 val = 0; - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x0C, SD_20_MODE); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, - CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1); - - if ((chip->option.sd_ctl & SD_PUSH_POINT_CTL_MASK) == - SD_PUSH_POINT_AUTO) { - val = SD20_TX_NEG_EDGE; - } else if ((chip->option.sd_ctl & SD_PUSH_POINT_CTL_MASK) == - SD_PUSH_POINT_DELAY) { - val = SD20_TX_14_AHEAD; - } else { - val = SD20_TX_NEG_EDGE; - } - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PUSH_POINT_CTL, - SD20_TX_SEL_MASK, val); - - if ((chip->option.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)) - val = SD20_RX_14_DELAY; - else - val = SD20_RX_POS_EDGE; - } else { - val = SD20_RX_14_DELAY; - } - } else if ((chip->option.sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == - SD_SAMPLE_POINT_DELAY) { - val = SD20_RX_14_DELAY; - } else { - val = SD20_RX_POS_EDGE; - } - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, - SD20_RX_SEL_MASK, val); - } - - if (CHK_MMC_DDR52(sd_card) && CHK_MMC_8BIT(sd_card)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, - EXTEND_DMA1_ASYNC_SIGNAL, 0); - } - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static void sd_choose_proper_clock(struct rts51x_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->option.asic_sd_sdr104_clk; - else - sd_card->sd_clock = chip->option.fpga_sd_sdr104_clk; - } else if (CHK_SD_DDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->option.asic_sd_ddr50_clk; - else - sd_card->sd_clock = chip->option.fpga_sd_ddr50_clk; - } else if (CHK_SD_SDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->option.asic_sd_sdr50_clk; - else - sd_card->sd_clock = chip->option.fpga_sd_sdr50_clk; - } else if (CHK_SD_HS(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->option.asic_sd_hs_clk; - else - sd_card->sd_clock = chip->option.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->option.asic_mmc_52m_clk; - else - sd_card->sd_clock = chip->option.fpga_mmc_52m_clk; - } else if (CHK_MMC_26M(sd_card)) { - if (chip->asic_code) { - sd_card->sd_clock = 46; - RTS51X_DEBUGP("Set MMC clock to 22.5MHz\n"); - } else { - sd_card->sd_clock = CLK_50; - } - } -} - -static int sd_set_init_para(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - sd_choose_proper_clock(chip); - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_sd_select_card(struct rts51x_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) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int sd_wait_currentstate_dataready(struct rts51x_chip *chip, u8 statechk, - u8 rdychk, u16 pollingcnt) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 rsp[5]; - u16 i; - - for (i = 0; i < pollingcnt; i++) { - - retval = - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, rsp, 5); - if (retval == STATUS_SUCCESS) { - if (((rsp[3] & 0x1E) == statechk) - && ((rsp[3] & 0x01) == rdychk)) { - return STATUS_SUCCESS; - } - } else { - rts51x_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - } - - return STATUS_TIMEDOUT; -} - -static int sd_voltage_switch(struct rts51x_chip *chip) -{ - int retval; - u8 stat; - - RTS51X_WRITE_REG(chip, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, - SD_CLK_TOGGLE_EN); - - retval = - sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, NULL, - 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_READ_REG(chip, SD_BUS_STAT, &stat); - if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BUS_STAT, 0xFF, - SD_CLK_FORCE_STOP); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PAD_CTL, SD_IO_USING_1V8, - SD_IO_USING_1V8); - if (chip->asic_code) - rts51x_add_cmd(chip, WRITE_REG_CMD, LDO_POWER_CFG, - TUNE_SD18_MASK, TUNE_SD18_1V8); - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - wait_timeout(chip->option.D3318_off_delay); - - RTS51X_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); - wait_timeout(10); - - RTS51X_READ_REG(chip, SD_BUS_STAT, &stat); - 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)) { - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BUS_STAT, 0xFF, - SD_CLK_FORCE_STOP); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, 0xFF, 0); - rts51x_send_cmd(chip, MODE_C, 100); - TRACE_RET(chip, STATUS_FAIL); - } - RTS51X_WRITE_REG(chip, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); - - return STATUS_SUCCESS; -} - -static int sd_change_phase(struct rts51x_chip *chip, u8 sample_point, - u8 tune_dir) -{ - u16 SD_VP_CTL, SD_DCMPS_CTL; - u8 val; - int retval; - - RTS51X_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n", - sample_point, tune_dir); - - if (tune_dir == TUNE_RX) { - SD_VP_CTL = SD_VPCLK1_CTL; - SD_DCMPS_CTL = SD_DCMPS1_CTL; - } else { - SD_VP_CTL = SD_VPCLK0_CTL; - SD_DCMPS_CTL = SD_DCMPS0_CTL; - } - - if (chip->asic_code) { - RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, CLK_CHANGE); - RTS51X_WRITE_REG(chip, SD_VP_CTL, 0x1F, sample_point); - RTS51X_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); - RTS51X_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, - PHASE_NOT_RESET); - RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); - } else { -#ifdef CONFIG_RTS5139_DEBUG - RTS51X_READ_REG(chip, SD_VP_CTL, &val); - RTS51X_DEBUGP("SD_VP_CTL: 0x%x\n", val); - RTS51X_READ_REG(chip, SD_DCMPS_CTL, &val); - RTS51X_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); -#endif - - RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, CLK_CHANGE); - udelay(100); - RTS51X_WRITE_REG(chip, SD_VP_CTL, 0xFF, - PHASE_NOT_RESET | sample_point); - udelay(200); - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, - DCMPS_CHANGE); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, - DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, Fail); - - retval = rts51x_get_rsp(chip, 1, 500); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, Fail); - - val = chip->rsp_buf[0]; - if (val & DCMPS_ERROR) - TRACE_GOTO(chip, Fail); - if ((val & DCMPS_CURRENT_PHASE) != sample_point) - TRACE_GOTO(chip, Fail); - RTS51X_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); - RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); - udelay(100); - } - - RTS51X_WRITE_REG(chip, SD_CFG1, SD_ASYNC_FIFO_RST, 0); - - return STATUS_SUCCESS; - -Fail: -#ifdef CONFIG_RTS5139_DEBUG - rts51x_ep0_read_register(chip, SD_VP_CTL, &val); - RTS51X_DEBUGP("SD_VP_CTL: 0x%x\n", val); - rts51x_ep0_read_register(chip, SD_DCMPS_CTL, &val); - RTS51X_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); -#endif - - RTS51X_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); - RTS51X_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0); - wait_timeout(10); - - return STATUS_FAIL; -} - -static int sd_check_spec(struct rts51x_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) - TRACE_RET(chip, 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) { - rts51x_clear_sd_error(chip); - TRACE_RET(chip, retval); - } - - memcpy(sd_card->raw_scr, buf, 8); - - if ((buf[0] & 0x0F) == 0) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_query_switch_result(struct rts51x_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: - TRACE_RET(chip, 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: - TRACE_RET(chip, 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: - TRACE_RET(chip, STATUS_FAIL); - } - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - if (func_group == SD_FUNC_GROUP_4) - buf[query_switch_offset] = - (buf[query_switch_offset] & 0xf0) >> 4; - if (!(buf[support_offset] & support_mask) || - ((buf[query_switch_offset] & 0x0F) != query_switch)) - TRACE_RET(chip, STATUS_FAIL); - - if ((buf[DATA_STRUCTURE_VER_OFFSET] == 0x01) && - ((buf[check_busy_offset] & switch_busy) == switch_busy)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_check_switch_mode(struct rts51x_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]; - - RTS51X_DEBUGP("sd_check_switch_mode (mode = %d, func_group = %d," - "func_to_switch = %d)\n", 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) { - rts51x_clear_sd_error(chip); - TRACE_RET(chip, retval); - } - - 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]; - - RTS51X_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]); - RTS51X_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]); - RTS51X_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]); - RTS51X_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]); - } else { - if ((buf[0] == 0) && (buf[1] == 0)) - TRACE_RET(chip, STATUS_FAIL); - retval = - sd_query_switch_result(chip, func_group, func_to_switch, - buf, 64); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int sd_check_switch(struct rts51x_chip *chip, - u8 func_group, u8 func_to_switch, u8 bus_width) -{ - int retval; - int i; - int switch_good = 0; - - for (i = 0; i < 3; i++) { - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - sd_set_reset_fail(chip, SD_RESET_FAIL); - TRACE_RET(chip, 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 = 1; - break; - } - - RTS51X_READ_REG(chip, SD_STAT1, &stat); - - if (stat & SD_CRC16_ERR) { - RTS51X_DEBUGP("SD CRC16 error when switching" - "mode\n"); - TRACE_RET(chip, STATUS_FAIL); - } - } - - wait_timeout(20); - } - - if (!switch_good) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_switch_function(struct rts51x_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) - TRACE_RET(chip, retval); - - sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); - - for (i = 0; i < 4; i++) { - switch ((u8) (chip->option.sd_speed_prior >> (i * 8))) { - case DDR50_SUPPORT: - if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK) - && (CHECK_UHS50(chip))) - func_to_switch = DDR50_SUPPORT; - break; - - case SDR50_SUPPORT: - if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK) - && (CHECK_UHS50(chip))) - 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; - } - RTS51X_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", - func_to_switch); - - 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 = DDR50_SUPPORT_MASK; - else if (func_to_switch == SDR50_SUPPORT) - sd_card->sd_switch_fail = SDR50_SUPPORT_MASK; - else if (func_to_switch == HS_SUPPORT) - sd_card->sd_switch_fail = HS_SUPPORT_MASK; - - TRACE_RET(chip, retval); - } - - 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)) - RTS51X_WRITE_REG(chip, SD_CFG1, 0x0C, SD_DDR_MODE); - - func_to_switch = 0; - if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) - func_to_switch = CURRENT_LIMIT_400; - - if (func_to_switch) { - RTS51X_DEBUGP("Try to switch current_limit_400\n"); - retval = - sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, - bus_width); - RTS51X_DEBUGP("Switch current_limit_400 status: (%d)\n", - retval); - } - - return STATUS_SUCCESS; -} - -static int sd_wait_data_idle(struct rts51x_chip *chip) -{ - int retval = STATUS_TIMEDOUT; - int i; - u8 val = 0; - - for (i = 0; i < 100; i++) { - retval = rts51x_ep0_read_register(chip, SD_DATA_STATE, &val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - if (val & SD_DATA_IDLE) { - retval = STATUS_SUCCESS; - break; - } - udelay(100); - } - RTS51X_DEBUGP("SD_DATA_STATE: 0x%02x\n", val); - - return retval; -} - -static int sd_sdr_tuning_rx_cmd(struct rts51x_chip *chip, u8 sample_point) -{ - int retval; - u8 cmd[5]; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) { - /* Wait till SD DATA IDLE */ - (void)sd_wait_data_idle(chip); - - rts51x_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_rx_cmd(struct rts51x_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) - TRACE_RET(chip, retval); - - RTS51X_DEBUGP("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) - TRACE_RET(chip, retval); - - 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) { - /* Wait till SD DATA IDLE */ - (void)sd_wait_data_idle(chip); - - rts51x_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tunning_rx_cmd(struct rts51x_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) - TRACE_RET(chip, retval); - - RTS51X_DEBUGP("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) { - /* Wait till SD DATA IDLE */ - (void)sd_wait_data_idle(chip); - - rts51x_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning_tx_cmd(struct rts51x_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) - TRACE_RET(chip, retval); - - RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - - 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)) { - /* Tunning TX fail */ - rts51x_ep0_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_tx_cmd(struct rts51x_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) - TRACE_RET(chip, retval); - - 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_currentstate_dataready(chip, 0x08, 1, 20); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - - 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) { - rts51x_clear_sd_error(chip); - /* Tunning TX fail */ - rts51x_ep0_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - TRACE_RET(chip, STATUS_FAIL); - } - - RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - - 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 rts51x_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; - int new_block, max_len; - u8 final_phase = 0xFF; - int final_path_idx; - - if (phase_map == 0xffff) { - if (CHK_SD_DDR50(sd_card)) { - if (tune_dir == TUNE_TX) - final_phase = chip->option.ddr50_tx_phase; - else - final_phase = chip->option.ddr50_rx_phase; - RTS51X_DEBUGP("DDR50 tuning dir:%d all pass," - "so select default phase:0x%x.\n", - tune_dir, final_phase); - } else { - if (tune_dir == TUNE_TX) - final_phase = chip->option.sdr50_tx_phase; - else - final_phase = chip->option.sdr50_rx_phase; - RTS51X_DEBUGP("SDR50 tuning dir:%d all pass," - "so select default phase:0x%x.\n", - tune_dir, final_phase); - } - goto Search_Finish; - } - - cont_path_cnt = 0; - new_block = 1; - j = 0; - for (i = 0; i < MAX_PHASE + 1; i++) { - if (phase_map & (1 << i)) { - if (new_block) { - new_block = 0; - j = cont_path_cnt++; - path[j].start = i; - path[j].end = i; - } else { - path[j].end = i; - } - } else { - new_block = 1; - 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) { - RTS51X_DEBUGP("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; - } - - RTS51X_DEBUGP("path[%d].start = %d\n", i, path[i].start); - RTS51X_DEBUGP("path[%d].end = %d\n", i, path[i].end); - RTS51X_DEBUGP("path[%d].len = %d\n", i, path[i].len); - RTS51X_DEBUGP("path[%d].mid = %d\n", i, path[i].mid); - RTS51X_DEBUGP("\n"); - } - - if ((tune_dir == TUNE_TX) && (CHK_SD_SDR50(sd_card)) - && chip->option.sdr50_phase_sel) { - if (max_len > 6) { - int temp_mid = (max_len - 6) / 2; - int temp_final_phase = - path[final_path_idx].end - (max_len - - (3 + temp_mid)); - - if (temp_final_phase < 0) - final_phase = temp_final_phase + MAX_PHASE + 1; - else - final_phase = (u8) temp_final_phase; - } - } - -Search_Finish: - RTS51X_DEBUGP("Final chosen phase: %d\n", final_phase); - return final_phase; -} - -static int sd_tuning_rx(struct rts51x_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 rts51x_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_tunning_rx_cmd; - else - TRACE_RET(chip, STATUS_FAIL); - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - sd_set_reset_fail(chip, SD_RESET_FAIL); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = tuning_cmd(chip, (u8) j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - else - RTS51X_DEBUGP("Tuning phase %d fail\n", j); - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - RTS51X_DEBUGP("RX raw_phase_map[%d] = 0x%04x\n", i, - raw_phase_map[i]); - RTS51X_DEBUGP("RX phase_map = 0x%04x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); - if (final_phase == 0xFF) - TRACE_RET(chip, STATUS_FAIL); - - retval = tuning_cmd(chip, final_phase); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int sd_ddr_pre_tuning_tx(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 i; - u8 pre_tune_tx_phase; - u32 pre_tune_phase_map; - - RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - - pre_tune_tx_phase = 0xFF; - pre_tune_phase_map = 0x0000; - for (i = 0; i < MAX_PHASE + 1; i++) { - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - sd_set_reset_fail(chip, SD_RESET_FAIL); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_change_phase(chip, (u8) i, TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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)) - pre_tune_phase_map |= (u32) 1 << i; - } - - RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - - pre_tune_tx_phase = - sd_search_final_phase(chip, pre_tune_phase_map, TUNE_TX); - if (pre_tune_tx_phase == 0xFF) - TRACE_RET(chip, STATUS_FAIL); - - sd_change_phase(chip, pre_tune_tx_phase, TUNE_TX); - RTS51X_DEBUGP("DDR TX pre tune phase: %d\n", (int)pre_tune_tx_phase); - - return STATUS_SUCCESS; -} - -static int sd_tuning_tx(struct rts51x_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 rts51x_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 - TRACE_RET(chip, STATUS_FAIL); - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - sd_set_reset_fail(chip, SD_RESET_FAIL); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = tuning_cmd(chip, (u8) j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - else - RTS51X_DEBUGP("Tuning phase %d fail\n", j); - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - RTS51X_DEBUGP("TX raw_phase_map[%d] = 0x%04x\n", i, - raw_phase_map[i]); - RTS51X_DEBUGP("TX phase_map = 0x%04x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) - TRACE_RET(chip, STATUS_FAIL); - - retval = tuning_cmd(chip, final_phase); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning(struct rts51x_chip *chip) -{ - int retval; - - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning(struct rts51x_chip *chip) -{ - int retval; - - if (!(chip->option.sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - retval = - sd_change_phase(chip, (u8) chip->option.sd_ddr_tx_phase, - TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (!(chip->option.sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tuning(struct rts51x_chip *chip) -{ - int retval; - - if (!(chip->option.sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - retval = - sd_change_phase(chip, (u8) chip->option.mmc_ddr_tx_phase, - TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (!(chip->option.sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -int rts51x_sd_switch_clock(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int re_tuning = 0; - - retval = rts51x_select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) { - if (sd_card->sd_clock != chip->cur_clk) - re_tuning = 1; - } - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int sd_prepare_reset(struct rts51x_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; - - /* Set SD Clocks */ - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0xFF, - SD_CLK_DIVIDE_128 | SD_20_MODE | SD_BUS_WIDTH_1); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, 0xFF, - SD20_RX_POS_EDGE); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PUSH_POINT_CTL, 0xFF, 0); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static void sd_pull_ctl_disable(struct rts51x_chip *chip) -{ - if (CHECK_PKG(chip, LQFP48)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); - } -} - -static void sd_pull_ctl_enable(struct rts51x_chip *chip) -{ - if (CHECK_PKG(chip, LQFP48)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xA9); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA5); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x9A); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xA5); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x9A); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x65); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x5A); - } -} - -static int sd_init_power(struct rts51x_chip *chip) -{ - int retval; - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, LDO3318_PWR_MASK, - LDO_ON); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PAD_CTL, SD_IO_USING_1V8, - SD_IO_USING_3V3); - if (chip->asic_code) - rts51x_add_cmd(chip, WRITE_REG_CMD, LDO_POWER_CFG, - TUNE_SD18_MASK, TUNE_SD18_3V3); - if (chip->asic_code) - sd_pull_ctl_disable(chip); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, - FPGA_SD_PULL_CTL_BIT); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0); - if (!chip->option.FT2_fast_mode) - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (!chip->option.FT2_fast_mode) { -#ifdef SD_XD_IO_FOLLOW_PWR - if (CHECK_PKG(chip, LQFP48) - || chip->option.rts5129_D3318_off_enable) - rts51x_write_register(chip, CARD_PWR_CTL, - LDO_OFF, LDO_OFF); -#endif - wait_timeout(250); - -#ifdef SD_XD_IO_FOLLOW_PWR - if (CHECK_PKG(chip, LQFP48) - || chip->option.rts5129_D3318_off_enable) { - rts51x_init_cmd(chip); - if (chip->asic_code) - sd_pull_ctl_enable(chip); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, - FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, 0); - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - if (chip->asic_code) - rts51x_write_register(chip, CARD_PULL_CTL6, - 0x03, 0x00); - } -#endif - - /* Power on card */ - retval = rts51x_card_power_on(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - wait_timeout(260); - -#ifdef SUPPORT_OCP - rts51x_get_card_status(chip, &(chip->card_status)); - chip->ocp_stat = (chip->card_status >> 4) & 0x03; - - if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { - RTS51X_DEBUGP("Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - - rts51x_init_cmd(chip); - if (chip->asic_code) { - sd_pull_ctl_enable(chip); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, 0); - } - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#ifdef SD_XD_IO_FOLLOW_PWR - rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT, - XD_INT | MS_INT | SD_INT); -#endif - - RTS51X_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); - - return STATUS_SUCCESS; -} - -static int sd_dummy_clock(struct rts51x_chip *chip) -{ - RTS51X_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN); - wait_timeout(5); - RTS51X_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00); - - return STATUS_SUCCESS; -} - -int reset_sd(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0; - int sd_dont_switch = 0; - int support_1v8 = 0; - u8 rsp[16]; - u8 switch_bus_width; - u32 voltage = 0; - u8 cmd[5], buf[64]; - u16 sd_card_type; - - SET_SD(sd_card); - CLR_RETRY_SD20_MODE(sd_card); -Switch_Fail: - i = 0; - j = 0; - k = 0; - hi_cap_flow = 0; - support_1v8 = 0; - - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - sd_dummy_clock(chip); - - /* 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) - TRACE_RET(chip, retval); - - 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 = 1; - if (CHK_RETRY_SD20_MODE(sd_card)) { - voltage = - SUPPORT_VOLTAGE | - SUPPORT_HIGH_AND_EXTENDED_CAPACITY; - } else { - voltage = - SUPPORT_VOLTAGE | - SUPPORT_HIGH_AND_EXTENDED_CAPACITY | - SUPPORT_MAX_POWER_PERMANCE | SUPPORT_1V8; - } - } - } - - 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) - TRACE_RET(chip, retval); - wait_timeout(20); - } - - /* ACMD41 */ - do { - { - u8 temp = 0; - rts51x_read_register(chip, CARD_INT_PEND, &temp); - RTS51X_DEBUGP("CARD_INT_PEND:%x\n", temp); - if (temp & SD_INT) { - chip->reset_need_retry = 1; - rts51x_write_register(chip, CARD_INT_PEND, - XD_INT | SD_INT | MS_INT, - XD_INT | SD_INT | MS_INT); - sd_set_reset_fail(chip, SD_RESET_FAIL); - TRACE_RET(chip, STATUS_FAIL); - } - } - -RTY_CMD55: - retval = - sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, NULL, - 0); - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - sd_set_reset_fail(chip, SD_RESET_FAIL); - TRACE_RET(chip, STATUS_FAIL); - } - - j++; - if (chip->option.speed_mmc) { - if (j < 2) - goto RTY_CMD55; - else - TRACE_RET(chip, STATUS_FAIL); - } else { - if (j < 3) - goto RTY_SD_RST; - else - TRACE_RET(chip, 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 - TRACE_RET(chip, STATUS_FAIL); - } - - i++; - wait_timeout(20); - } while (!(rsp[1] & 0x80) && (i < 255)); /* Not complete power on */ - - if (i == 255) { - /* Time out */ - TRACE_RET(chip, STATUS_FAIL); - } - - if (hi_cap_flow) { - if (rsp[1] & 0x40) - SET_SD_HCXC(sd_card); - else - CLR_SD_HCXC(sd_card); - if (!CHK_RETRY_SD20_MODE(sd_card)) { - if ((CHK_SD_HCXC(sd_card)) && (CHECK_UHS50(chip))) { - support_1v8 = (rsp[1] & 0x01) ? 1 : 0; - RTS51X_DEBUGP("support_1v8 = %d\n", - support_1v8); - } - } - } else { - CLR_SD_HCXC(sd_card); - support_1v8 = 0; - } - - /* CMD11: Switch Voltage */ - if (support_1v8 && CHECK_UHS50(chip) - && !(((u8) chip->option.sd_speed_prior & SDR104_SUPPORT) == - HS_SUPPORT)) { - retval = sd_voltage_switch(chip); - if (retval != STATUS_SUCCESS) { - SET_RETRY_SD20_MODE(sd_card); - sd_init_power(chip); - RTS51X_DEBUGP("1.8v switch fail\n"); - goto Switch_Fail; - } - } - - /* CMD 2 */ - retval = - sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - /* CMD 3 */ - retval = - sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, SD_RSP_TYPE_R6, - rsp, 5); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - sd_card->sd_addr = (u32) rsp[1] << 24; - sd_card->sd_addr += (u32) rsp[2] << 16; - - /* Get CSD register for Calculating Timing,Capacity, - * Check CSD to determine as if this is the SD ROM card */ - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Select SD card */ - retval = rts51x_sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - /* ACMD42 */ - retval = - sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (support_1v8) { - /* ACMD6 */ - retval = - sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Enable 4 bit data bus */ - retval = - sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - switch_bus_width = SD_BUS_WIDTH_4; - } else { - switch_bus_width = SD_BUS_WIDTH_1; - } - - /* Set block length 512 bytes for all block commands */ - retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, - 0x200, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_WRITE_REG(chip, SD_CFG1, SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); - - if (!(sd_card->raw_csd[4] & 0x40)) { - sd_dont_switch = 1; - RTS51X_DEBUGP("Not support class ten\n"); - } - - if (!sd_dont_switch) { - /* Check the card whether flow 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) { - if ((sd_card->sd_switch_fail == - SDR104_SUPPORT_MASK) - || (sd_card->sd_switch_fail == - DDR50_SUPPORT_MASK) - || (sd_card->sd_switch_fail == - SDR50_SUPPORT_MASK)) { - sd_init_power(chip); - SET_RETRY_SD20_MODE(sd_card); - } else if (sd_card->sd_switch_fail == - HS_SUPPORT_MASK) { - sd_dont_switch = 1; - } - goto Switch_Fail; - } - } else { - if (support_1v8) { - SET_RETRY_SD20_MODE(sd_card); - sd_init_power(chip); - sd_dont_switch = 1; - - goto Switch_Fail; - } - } - } - - if (!support_1v8) { - /* ACMD6 */ - retval = - sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Enable 4 bit data bus */ - retval = - sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - if (CHK_SD30_SPEED(sd_card)) { - rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, - 0x03); - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (CHK_SD_DDR50(sd_card)) - retval = sd_ddr_tuning(chip); - else - retval = sd_sdr_tuning(chip); - - if (retval != STATUS_SUCCESS) { - SET_RETRY_SD20_MODE(sd_card); - RTS51X_DEBUGP("tuning phase fail,goto SD20 mode\n"); - sd_init_power(chip); - CLR_SD30_SPEED(sd_card); - goto Switch_Fail; - } - if (STATUS_SUCCESS == - sd_wait_currentstate_dataready(chip, 0x08, 1, 20)) { - cmd[0] = 0x40 | READ_SINGLE_BLOCK; - cmd[1] = 0x00; - cmd[2] = 0x00; - cmd[3] = 0x00; - cmd[4] = 0x00; - retval = - sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 512, - 1, SD_BUS_WIDTH_4, NULL, 0, 600); - if (retval != STATUS_SUCCESS) { - SET_RETRY_SD20_MODE(sd_card); - RTS51X_DEBUGP("read lba0 fail," - "goto SD20 mode\n"); - sd_init_power(chip); - CLR_SD30_SPEED(sd_card); - goto Switch_Fail; - } - } - } - 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, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval == STATUS_SUCCESS) { - int ret; - cmd[0] = 0x40 | SEND_STATUS; - cmd[1] = 0x00; - cmd[2] = 0x00; - cmd[3] = 0x00; - cmd[4] = 0x00; - ret = - sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, - SD_BUS_WIDTH_4, buf, 64, 600); - if (ret == STATUS_SUCCESS) { - sd_card_type = ((u16) buf[2] << 8) | (u16) buf[3]; - RTS51X_DEBUGP("sd_card_type:0x%4x\n", sd_card_type); - if ((sd_card_type == 0x0001) - || (sd_card_type == 0x0002)) - chip->card_wp |= SD_CARD; - } else { - rts51x_clear_sd_error(chip); - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - } else { - rts51x_clear_sd_error(chip); - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - /* Check SD Machanical Write-Protect Switch */ - retval = rts51x_get_card_status(chip, &(chip->card_status)); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (chip->card_status & SD_WP) - chip->card_wp |= SD_CARD; - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; - - return STATUS_SUCCESS; -} - -static int mmc_test_switch_bus(struct rts51x_chip *chip, u8 width) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 buf[8] = { 0 }, bus_width; - 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) - TRACE_RET(chip, retval); - - 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 = sd_write_data(chip, SD_TM_AUTO_WRITE_3, - NULL, 0, byte_cnt, 1, bus_width, buf, len, 100); - if (retval != STATUS_SUCCESS) { - u8 val1 = 0, val2 = 0; - rts51x_ep0_read_register(chip, SD_STAT1, &val1); - rts51x_ep0_read_register(chip, SD_STAT2, &val2); - rts51x_clear_sd_error(chip); - if ((val1 & 0xE0) || val2) - TRACE_RET(chip, STATUS_FAIL); - } - RTS51X_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R); - - rts51x_init_cmd(chip); - - /* CMD14 */ - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | BUSTEST_R); - - if (width == MMC_8BIT_BUS) - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x08); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x04); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_NO_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_NORMAL_READ | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); - if (width == MMC_8BIT_BUS) { - len = 3; - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); - } else { - len = 2; - } - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, len, 100); - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - rts51x_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_read_rsp_buf(chip, 1, buf, 2); - - if (width == MMC_8BIT_BUS) { - RTS51X_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", - buf[0], buf[1]); - if ((buf[0] == 0xAA) && (buf[1] == 0x55)) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70600; - else - arg = 0x03B70200; - /* Switch MMC to 8-bit mode */ - 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 STATUS_SUCCESS; - } - } else { - RTS51X_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", buf[0]); - if (buf[0] == 0xA5) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70500; - else - arg = 0x03B70100; - /* Switch MMC to 4-bit mode */ - 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 STATUS_SUCCESS; - } - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int mmc_switch_timing_bus(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 card_type, card_type_mask = 0; - u8 buf[6]; - - CLR_MMC_HS(sd_card); - - RTS51X_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD); - - rts51x_init_cmd(chip); - - /* SEND_EXT_CSD command */ - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, - 0x40 | SEND_EXT_CSD); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 2); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END - | SD_CHECK_CRC7 | SD_RSP_LEN_6); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_NORMAL_READ | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0); - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0); - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0); - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0); - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 6, 1000); - - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - if (retval == STATUS_TIMEDOUT) { - rts51x_clear_sd_error(chip); - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_read_rsp_buf(chip, 0, buf, 6); - - if (buf[0] & SD_TRANSFER_ERR) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - TRACE_RET(chip, STATUS_FAIL); - } - if (CHK_MMC_SECTOR_MODE(sd_card)) - sd_card->capacity = - ((u32) buf[5] << 24) | ((u32) buf[4] << 16) | - ((u32) buf[3] << 8) | ((u32) buf[2]); - if (CHECK_UHS50(chip)) - card_type_mask = 0x07; - else - card_type_mask = 0x03; - - card_type = buf[1] & card_type_mask; - if (card_type) { - /* CARD TYPE FIELD = DDR52MHz, 52MHz or 26MHz */ - u8 rsp[5]; - - if (card_type & 0x04) - SET_MMC_DDR52(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) - TRACE_RET(chip, retval); - - /* Test Bus Procedure */ - if (mmc_test_switch_bus(chip, MMC_8BIT_BUS) == STATUS_SUCCESS) { - SET_MMC_8BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; - } else if (mmc_test_switch_bus(chip, MMC_4BIT_BUS) == STATUS_SUCCESS) { - SET_MMC_4BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; - } else { - CLR_MMC_8BIT(sd_card); - CLR_MMC_4BIT(sd_card); - } - - return STATUS_SUCCESS; -} - -static int reset_mmc(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, i = 0, j = 0, k = 0; - u8 rsp[16]; - u8 spec_ver = 0; - u8 change_to_ddr52 = 1; - u8 cmd[5]; - -MMC_DDR_FAIL: - - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, 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) - TRACE_RET(chip, retval); - - do { - { - u8 temp = 0; - rts51x_read_register(chip, CARD_INT_PEND, &temp); - if (temp & SD_INT) { - chip->reset_need_retry = 1; - rts51x_write_register(chip, CARD_INT_PEND, - XD_INT | SD_INT | MS_INT, - XD_INT | SD_INT | MS_INT); - sd_set_reset_fail(chip, MMC_RESET_FAIL); - TRACE_RET(chip, STATUS_FAIL); - } - } - - /* CMD 1 */ - retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND, - (SUPPORT_VOLTAGE | 0x40000000), - SD_RSP_TYPE_R3, rsp, 5); - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - sd_set_reset_fail(chip, MMC_RESET_FAIL); - TRACE_RET(chip, STATUS_FAIL); - } - - 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 { - TRACE_RET(chip, STATUS_FAIL); - } - } else { - j++; - if (j < 100) { - sd_clr_err_code(chip); - goto RTY_MMC_RST; - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - wait_timeout(20); - i++; - } while (!(rsp[1] & 0x80) && (i < 100)); /* Not complete power on */ - - if (i == 100) { - /* Time out */ - TRACE_RET(chip, STATUS_FAIL); - } - - if ((rsp[1] & 0x60) == 0x40) - SET_MMC_SECTOR_MODE(sd_card); - else - CLR_MMC_SECTOR_MODE(sd_card); - - /* CMD 2 */ - retval = - sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - /* CMD 3 */ - 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) - TRACE_RET(chip, retval); - - /* Get CSD register for Calculating Timing,Capacity - * Check CSD to determine as if this is the SD ROM card */ - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - /* Get MMC Spec_Ver in the CSD register */ - spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; - - /* Select MMC card */ - retval = rts51x_sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - /* Set block length 512 bytes for all block commands */ - retval = - sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, - 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_WRITE_REG(chip, SD_CFG1, SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); - - if (chip->ic_version < 2) - rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, - 0x02); - rts51x_write_register(chip, CARD_DRIVE_SEL, SD20_DRIVE_MASK, DRIVE_8mA); - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; - if (spec_ver == 4) { - /* MMC 4.x Cards */ - (void)mmc_switch_timing_bus(chip); - } - - if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_MMC_DDR52(sd_card) && change_to_ddr52) { - /* Card is extracted while identifying */ - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - CLR_MMC_DDR52(sd_card); - sd_init_power(chip); - change_to_ddr52 = 0; - goto MMC_DDR_FAIL; - } - - retval = mmc_ddr_tuning(chip); - if (retval != STATUS_SUCCESS) { - CLR_MMC_DDR52(sd_card); - sd_init_power(chip); - change_to_ddr52 = 0; - goto MMC_DDR_FAIL; - } - - if (STATUS_SUCCESS == - sd_wait_currentstate_dataready(chip, 0x08, 1, 20)) { - cmd[0] = 0x40 | READ_SINGLE_BLOCK; - cmd[1] = 0x00; - cmd[2] = 0x00; - cmd[3] = 0x00; - cmd[4] = 0x00; - if (CHK_MMC_8BIT(sd_card)) { - retval = - sd_read_data(chip, SD_TM_NORMAL_READ, cmd, - 5, 512, 1, SD_BUS_WIDTH_8, - NULL, 0, 600); - } else if (CHK_MMC_4BIT(sd_card)) { - retval = - sd_read_data(chip, SD_TM_NORMAL_READ, cmd, - 5, 512, 1, SD_BUS_WIDTH_4, - NULL, 0, 600); - } else { - retval = - sd_read_data(chip, SD_TM_NORMAL_READ, cmd, - 5, 512, 1, SD_BUS_WIDTH_1, - NULL, 0, 600); - } - - if (retval != STATUS_SUCCESS) { - CLR_MMC_DDR52(sd_card); - change_to_ddr52 = 0; - RTS51X_DEBUGP("read lba0 fail," - "goto SD20 mode\n"); - sd_init_power(chip); - goto MMC_DDR_FAIL; - } - } - } - - retval = rts51x_get_card_status(chip, &(chip->card_status)); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (chip->card_status & SD_WP) - chip->card_wp |= SD_CARD; - - return STATUS_SUCCESS; -} - -int rts51x_reset_sd_card(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i; - - memset(sd_card, 0, sizeof(struct sd_info)); - - /* Init variables */ - 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; - - sd_clear_reset_fail(chip); - rts51x_enable_card_clock(chip, SD_CARD); - - sd_init_power(chip); - - chip->reset_need_retry = 0; - for (i = 0; i < 3; i++) { - if (!chip->option.reset_mmc_first) { /* reset sd first */ - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - /* Switch SD bus to 3V3 signal */ - RTS51X_WRITE_REG(chip, SD_PAD_CTL, - SD_IO_USING_1V8, 0); - if (sd_check_reset_fail(chip, SD_RESET_FAIL)) - sd_clear_reset_fail(chip); - else - retval = reset_mmc(chip); - } - } else { /* reset MMC first */ - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) { - if (sd_check_reset_fail(chip, MMC_RESET_FAIL)) { - sd_clear_reset_fail(chip); - } else { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - /* Switch SD bus to - * 3V3 signal */ - RTS51X_WRITE_REG(chip, - SD_PAD_CTL, - SD_IO_USING_1V8, 0); - } - } - } - } - - if ((retval == STATUS_SUCCESS) || (!chip->reset_need_retry)) { - /* if reset success or don't need retry,then break */ - break; - } - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { - /* card is extracted */ - break; - } - RTS51X_DEBUGP("retry reset sd card,%d\n", i); - chip->reset_need_retry = 0; - } - - sd_clear_reset_fail(chip); - chip->reset_need_retry = 0; - - if (retval == STATUS_SUCCESS) { - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, SD_CLK_DIVIDE_MASK, - SD_CLK_DIVIDE_0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 2); - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; - if (chip->option.reset_or_rw_fail_set_pad_drive) { - rts51x_write_register(chip, CARD_DRIVE_SEL, - SD20_DRIVE_MASK, DRIVE_8mA); - } - TRACE_RET(chip, STATUS_FAIL); - } - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; - - if (chip->option.sd_send_status_en) { - sd_card->sd_send_status_en = 1; - } else { - if (sd_card->capacity > 0x20000) { /* 64MB */ - sd_card->sd_send_status_en = 0; - } else { - sd_card->sd_send_status_en = 1; - } - } - RTS51X_DEBUGP("sd_card->sd_send_status = %d\n", - sd_card->sd_send_status_en); - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type); - - return STATUS_SUCCESS; -} - -#define WAIT_DATA_READY_RTY_CNT 255 - -static int wait_data_buf_ready(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int i, retval; - - for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) { - if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, 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) - TRACE_RET(chip, retval); - - 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); - - TRACE_RET(chip, STATUS_FAIL); -} - -static void sd_stop_seq_mode(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - if (sd_card->seq_mode) { - retval = rts51x_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); - sd_card->seq_mode = 0; - - rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, - FIFO_FLUSH); - } -} - -static inline int sd_auto_tune_clock(struct rts51x_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 { - if (sd_card->sd_clock == CLK_100) - sd_card->sd_clock = CLK_80; - else if (sd_card->sd_clock == CLK_80) - sd_card->sd_clock = CLK_60; - else if (sd_card->sd_clock == CLK_60) - sd_card->sd_clock = CLK_50; - } - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, - u16 sector_cnt) -{ - struct sd_info *sd_card = &(chip->sd_card); - u32 data_addr; - int retval; - u8 flag; - unsigned int pipe; - u8 stageflag; - - sd_card->counter = 0; - - if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) - data_addr = start_sector << 9; - else - data_addr = start_sector; - - RTS51X_DEBUGP("rts51x_sd_rw, data_addr = 0x%x\n", data_addr); - - sd_clr_err_code(chip); - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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_dir == DMA_FROM_DEVICE) - && !CHK_SD30_SPEED(sd_card) - && !CHK_SD_HS(sd_card) - && !CHK_MMC_HS(sd_card) - && sd_card->sd_send_status_en) { - 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) { - sd_set_err_code(chip, SD_STS_ERR); - TRACE_RET(chip, sd_parse_err_code(chip)); - } - - sd_card->seq_mode = 0; - - RTS51X_WRITE_REG(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); - - if (!CHK_SD30_SPEED(sd_card) - && !CHK_SD_HS(sd_card) - && !CHK_MMC_HS(sd_card) - && sd_card->sd_send_status_en) { - /* random rw, so pre_sec_cnt < 0x80 */ - sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - } - } - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, - (u8) sector_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, - (u8) (sector_cnt >> 8)); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - RING_BUFFER); - - if (CHK_MMC_8BIT(sd_card)) - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, - SD_BUS_WIDTH_1); - - if (sd_card->seq_mode) { - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, - SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | - SD_RSP_LEN_0); - - rts51x_trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, - DMA_512); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - flag = MODE_CDIR; - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_3 | SD_TRANSFER_START); - } else { - flag = MODE_CDOR; - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - } - - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, flag, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - RTS51X_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, - 0x40 | READ_MULTIPLE_BLOCK); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, - (u8) (data_addr >> 24)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, - (u8) (data_addr >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, - (u8) (data_addr >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, - (u8) data_addr); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | - SD_RSP_LEN_6); - - rts51x_trans_dma_enable(srb->sc_data_direction, chip, - sector_cnt * 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDIR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - retval = rts51x_send_cmd(chip, MODE_C, 50); - if (retval != STATUS_SUCCESS) { - rts51x_clear_sd_error(chip); - - sd_set_err_code(chip, SD_TO_ERR); - TRACE_RET(chip, sd_parse_err_code(chip)); - } - - retval = wait_data_buf_ready(chip); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_TO_ERR); - TRACE_RET(chip, sd_parse_err_code(chip)); - } - - retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK, - data_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_CRC_ERR); - TRACE_RET(chip, sd_parse_err_code(chip)); - } - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, - SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | - SD_RSP_LEN_0); - - rts51x_trans_dma_enable(srb->sc_data_direction, chip, - sector_cnt * 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDOR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - sd_card->seq_mode = 1; - } - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - pipe = RCV_BULK_PIPE(chip); - stageflag = STAGE_DI; - } else { - pipe = SND_BULK_PIPE(chip); - stageflag = STAGE_DO; - } - - retval = - rts51x_transfer_data_rcc(chip, pipe, scsi_sglist(srb), - scsi_bufflen(srb), scsi_sg_count(srb), - NULL, 10000, stageflag); - if (retval != STATUS_SUCCESS) { - u8 stat = 0; - int err = retval; - - sd_print_debug_reg(chip); - - rts51x_ep0_read_register(chip, SD_STAT1, &stat); - RTS51X_DEBUGP("SD_STAT1: 0x%x\n", stat); - - rts51x_clear_sd_error(chip); - - 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); - TRACE_RET(chip, retval); - } - - if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) { - RTS51X_DEBUGP("SD CRC error, tune clock!\n"); - sd_auto_tune_clock(chip); - } - - sd_card->seq_mode = 0; - - TRACE_RET(chip, err); - } - retval = rts51x_get_rsp(chip, 1, 2000); - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - rts51x_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - 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; -} - -void rts51x_sd_cleanup_work(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - if (sd_card->seq_mode) { - RTS51X_DEBUGP("SD: stop transmission\n"); - sd_stop_seq_mode(chip); - sd_card->counter = 0; - } -} - -static inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) -{ - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0); - if (!chip->option.FT2_fast_mode) { -#ifdef SD_XD_IO_FOLLOW_PWR - if (CHECK_PKG(chip, LQFP48) - || chip->option.rts5129_D3318_off_enable) - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, - POWER_MASK | LDO_OFF, - POWER_OFF | LDO_OFF); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, - POWER_MASK, POWER_OFF); -#else - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); -#endif - } -} - -static int sd_power_off_card3v3(struct rts51x_chip *chip) -{ - int retval; - - rts51x_init_cmd(chip); - - sd_fill_power_off_card3v3(chip); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#ifdef SD_XD_IO_FOLLOW_PWR - if (!chip->option.FT2_fast_mode) - wait_timeout(chip->option.D3318_off_delay); -#endif - - return STATUS_SUCCESS; -} - -int rts51x_release_sd_card(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - RTS51X_DEBUGP("rts51x_release_sd_card\n"); - - chip->card_ready &= ~SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->card_wp &= ~SD_CARD; - - memset(sd_card->raw_csd, 0, 16); - memset(sd_card->raw_scr, 0, 8); - - rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); - rts51x_write_register(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0); - if (CHECK_PKG(chip, LQFP48) || chip->option.rts5129_D3318_off_enable) - sd_power_off_card3v3(chip); - - rts51x_init_cmd(chip); - if (!(CHECK_PKG(chip, LQFP48) || chip->option.rts5129_D3318_off_enable)) - sd_fill_power_off_card3v3(chip); - - if (chip->asic_code) - sd_pull_ctl_disable(chip); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, - FPGA_SD_PULL_CTL_BIT); - - /* Switch LDO3318 to 3.3V */ - rts51x_add_cmd(chip, WRITE_REG_CMD, LDO_POWER_CFG, TUNE_SD18_MASK, - TUNE_SD18_3V3); - - if (CHK_MMC_DDR52(sd_card) && CHK_MMC_8BIT(sd_card)) - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, - EXTEND_DMA1_ASYNC_SIGNAL, - EXTEND_DMA1_ASYNC_SIGNAL); - if (CHK_SD30_SPEED(sd_card) || CHK_MMC(sd_card)) - rts51x_add_cmd(chip, WRITE_REG_CMD, SD30_DRIVE_SEL, - SD30_DRIVE_MASK, chip->option.sd30_pad_drive); - /* Suspend LDO3318 */ - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, LDO3318_PWR_MASK, - LDO_SUSPEND); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - wait_timeout(20); - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5139/sd.h b/drivers/staging/rts5139/sd.h deleted file mode 100644 index 7dd943f54c74..000000000000 --- a/drivers/staging/rts5139/sd.h +++ /dev/null @@ -1,275 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_SD_H -#define __RTS51X_SD_H - -#include "rts51x_chip.h" - -#define SD_MAX_RETRY_COUNT 3 - -#define SUPPORT_VOLTAGE 0x003C0000 - -#define SD_RESET_FAIL 0x01 -#define MMC_RESET_FAIL 0x02 - -/* 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 - -/* MMC/SD Command Index */ -/* Basic command (class 0) */ -#define GO_IDLE_STATE 0 -#define SEND_OP_COND 1 /* reserved for SD */ -#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 -/* end */ -#define SEND_CSD 9 -#define SEND_CID 10 -#define VOLTAGE_SWITCH 11 -#define READ_DAT_UTIL_STOP 11 /* reserved for SD */ -#define STOP_TRANSMISSION 12 -#define SEND_STATUS 13 -#define GO_INACTIVE_STATE 15 - -/* Block oriented read commands (class 2) */ -#define SET_BLOCKLEN 16 -#define READ_SINGLE_BLOCK 17 -#define READ_MULTIPLE_BLOCK 18 -#define SEND_TUNING_PATTERN 19 - -/* Bus Width Test */ -#define BUSTEST_R 14 -#define BUSTEST_W 19 -/* end */ - -/* Block oriented write commands (class 4) */ -#define WRITE_BLOCK 24 -#define WRITE_MULTIPLE_BLOCK 25 -#define PROGRAM_CSD 27 - -/* Erase commands */ -#define ERASE_WR_BLK_START 32 -#define ERASE_WR_BLK_END 33 -#define ERASE_CMD 38 - -/* Block Oriented Write Protection Commands */ -#define LOCK_UNLOCK 42 - -#define IO_RW_DIRECT 52 - -/* Application specific commands (class 8) */ -#define APP_CMD 55 -#define GEN_CMD 56 - -/* SD Application command Index */ -#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 - -/* SD TIMEOUT function return error */ -#define SD_READ_COMPLETE 0x00 -#define SD_READ_TO 0x01 -#define SD_READ_ADVENCE 0x02 - -/* SD v1.1 CMD6 SWITCH function */ -#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 - -/* SD Command Argument */ -#define NO_ARGUMENT 0x00 -#define CHECK_PATTERN 0x000000AA -#define VOLTAGE_SUPPLY_RANGE 0x00000100 /* 2.7~3.6V */ -#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000 -#define SUPPORT_MAX_POWER_PERMANCE 0x10000000 -#define SUPPORT_1V8 0x01000000 - -/* Switch Command Error Code */ -#define SWTICH_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 - -/* Function Group Definition */ -/* Function Group 1 */ -#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 -/* Function Group 3 */ -#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 -/* Function Group 4 */ -#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 -/* Switch Function Status Offset */ -#define DATA_STRUCTURE_VER_OFFSET 0x11 /* The high offset */ -#define MAX_PHASE 15 -/* #define TOTAL_READ_PHASE 0x20 */ -/* #define TOTAL_WRITE_PHASE 0x20 */ -/* MMC v4.0 */ -/* #define MMC_52MHZ_SPEED 0x0001 */ -/* #define MMC_26MHZ_SPEED 0x0002 */ -#define MMC_8BIT_BUS 0x0010 -#define MMC_4BIT_BUS 0x0020 -/* #define MMC_SECTOR_MODE 0x0100 */ -#define MMC_SWITCH_ERR 0x80 -/* Tuning direction RX or TX */ -#define TUNE_TX 0x00 -#define TUNE_RX 0x01 -/* For Change_DCM_FreqMode Function */ -#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 -/* For Change_FPGA_SSCClock Function */ -#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 -#define CHECK_SD_TRANS_FAIL(chip, retval) \ - (((retval) != STATUS_SUCCESS) || \ - (chip->rsp_buf[0] & SD_TRANSFER_ERR)) -/* SD Tuning Data Structure */ -/* Record continuous timing phase path */ -struct timing_phase_path { - int start; - int end; - int mid; - int len; -}; - -int rts51x_sd_select_card(struct rts51x_chip *chip, int select); -int rts51x_reset_sd_card(struct rts51x_chip *chip); -int rts51x_sd_switch_clock(struct rts51x_chip *chip); -int rts51x_sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, - u16 sector_cnt); -void rts51x_sd_cleanup_work(struct rts51x_chip *chip); -int rts51x_release_sd_card(struct rts51x_chip *chip); - -#ifdef SUPPORT_CPRM -extern int reset_sd(struct rts51x_chip *chip); -extern int sd_check_data0_status(struct rts51x_chip *chip); -extern int sd_read_data(struct rts51x_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); -#endif - -#endif /* __RTS51X_SD_H */ diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c deleted file mode 100644 index cede6c07394f..000000000000 --- a/drivers/staging/rts5139/sd_cprm.c +++ /dev/null @@ -1,1056 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include "debug.h" -#include "trace.h" -#include "rts51x.h" -#include "rts51x_transport.h" -#include "rts51x_scsi.h" -#include "rts51x_card.h" -#include "rts51x_chip.h" -#include "sd_cprm.h" -#include "sd.h" - -#ifdef SUPPORT_CPRM - -static inline int get_rsp_type(u8 rsp_code, u8 *rsp_type, int *rsp_len) -{ - if (!rsp_type || !rsp_len) - return STATUS_FAIL; - - switch (rsp_code) { - case 0x03: - *rsp_type = SD_RSP_TYPE_R0; /* no response */ - *rsp_len = 0; - break; - - case 0x04: - *rsp_type = SD_RSP_TYPE_R1; /* R1,R6(,R4,R5) */ - *rsp_len = 6; - break; - - case 0x05: - *rsp_type = SD_RSP_TYPE_R1b; /* R1b */ - *rsp_len = 6; - break; - - case 0x06: - *rsp_type = SD_RSP_TYPE_R2; /* R2 */ - *rsp_len = 17; - break; - - case 0x07: - *rsp_type = SD_RSP_TYPE_R3; /* R3 */ - *rsp_len = 6; - break; - - default: - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, - int special_check) -{ - int retval; - int timeout = 50; - u16 reg_addr; - u8 buf[17], stat; - int len = 2; - int rty_cnt = 0; - - RTS51X_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8) (arg >> 24)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8) (arg >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8) (arg >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, - 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - rts51x_add_cmd(chip, READ_REG_CMD, SD_STAT1, 0, 0); - - if (CHECK_USB(chip, USB_20)) { - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; - reg_addr < PPBUF_BASE2 + 16; reg_addr++) { - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, - 0); - } - len = 19; - } else if (rsp_type != SD_RSP_TYPE_R0) { - /* Read data from SD_CMDx registers */ - for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; - reg_addr++) { - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, - 0); - } - len = 8; - } else { - len = 3; - } - rts51x_add_cmd(chip, READ_REG_CMD, SD_CMD5, 0, 0); - } else { - len = 2; - } - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, len, timeout); - - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - rts51x_clear_sd_error(chip); - - if (retval == STATUS_TIMEDOUT) { - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - } - TRACE_RET(chip, STATUS_FAIL); - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - if (CHECK_USB(chip, USB_20)) { - rts51x_read_rsp_buf(chip, 2, buf, len - 2); - } else { - if (rsp_type == SD_RSP_TYPE_R2) { - reg_addr = PPBUF_BASE2; - len = 16; - } else { - reg_addr = SD_CMD0; - len = 5; - } - retval = - rts51x_seq_read_register(chip, reg_addr, - (unsigned short)len, buf); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - RTS51X_READ_REG(chip, SD_CMD5, buf + len); - } - stat = chip->rsp_buf[1]; - - if ((buf[0] & 0xC0) != 0) - TRACE_RET(chip, STATUS_FAIL); - - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (stat & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) - TRACE_RET(chip, STATUS_FAIL); - if (rty_cnt < SD_MAX_RETRY_COUNT) { - wait_timeout(20); - rty_cnt++; - goto RTY_SEND_CMD; - } else { - TRACE_RET(chip, 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 == 0)) { - if (buf[1] & 0x80) - TRACE_RET(chip, STATUS_FAIL); - } - if (buf[1] & 0x7F) - TRACE_RET(chip, STATUS_FAIL); - if (buf[2] & 0xF8) - TRACE_RET(chip, STATUS_FAIL); - - if (cmd_idx == SELECT_CARD) { - if (rsp_type == SD_RSP_TYPE_R2) { - if ((buf[3] & 0x1E) != 0x04) - TRACE_RET(chip, STATUS_FAIL); - } else if (rsp_type == SD_RSP_TYPE_R2) { - if ((buf[3] & 0x1E) != 0x03) - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - if (rsp && rsp_len) - memcpy(rsp, buf, rsp_len); - - return STATUS_SUCCESS; -} - -static int ext_sd_get_rsp(struct rts51x_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; - - rts51x_init_cmd(chip); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; - reg_addr++) { - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - } - rsp_len = 17; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; reg_addr++) - rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - rsp_len = 6; - } - rts51x_add_cmd(chip, READ_REG_CMD, SD_CMD5, 0xFF, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, rsp_len, 100); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (rsp) { - int min_len = (rsp_len < len) ? rsp_len : len; - - memcpy(rsp, rts51x_get_rsp_data(chip), min_len); - - RTS51X_DEBUGP("min_len = %d\n", min_len); - RTS51X_DEBUGP("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 ext_rts51x_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, - u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code, - u32 arg) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, rsp_len; - u8 rsp_type; - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - sd_card->last_rsp_type = rsp_type; - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - /* Set H/W SD/MMC Bus Width */ - rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); - - if (standby) { - retval = rts51x_sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, 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, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - - if (standby) { - retval = rts51x_sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } - - return TRANSPORT_GOOD; - -SD_Execute_Cmd_Failed: - sd_card->pre_cmd_err = 1; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - rts51x_release_sd_card(chip); - rts51x_do_rts51x_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - TRACE_RET(chip, TRANSPORT_FAILED); -} - -int ext_rts51x_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, - u8 cmd_idx, u8 cmd12, u8 standby, - u8 acmd, u8 rsp_code, u32 arg, u32 data_len, - void *data_buf, unsigned int buf_len, int use_sg) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, rsp_len, i; - int cmd13_checkbit = 0, read_err = 0; - u8 rsp_type, bus_width; - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - sd_card->last_rsp_type = rsp_type; - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - bus_width = SD_BUS_WIDTH_4; - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (standby) { - retval = rts51x_sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, 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, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (data_len <= 512) { - int min_len; - u8 *buf; - u16 byte_cnt, blk_cnt; - u8 cmd[5]; - unsigned int offset = 0; - void *sg = NULL; - - byte_cnt = (u16) (data_len & 0x3FF); - blk_cnt = 1; - - cmd[0] = 0x40 | cmd_idx; - cmd[1] = (u8) (arg >> 24); - cmd[2] = (u8) (arg >> 16); - cmd[3] = (u8) (arg >> 8); - cmd[4] = (u8) arg; - - buf = kmalloc(data_len, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, 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 = 1; - kfree(buf); - rts51x_write_register(chip, CARD_STOP, - SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - min_len = min(data_len, buf_len); - if (use_sg) - rts51x_access_sglist(buf, min_len, (void *)data_buf, - &sg, &offset, TO_XFER_BUF); - else - memcpy(data_buf, buf, min_len); - - kfree(buf); - } else if (!(data_len & 0x1FF)) { - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, - 0xFF, (u8) (data_len >> 17)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, - 0xFF, (u8) ((data_len & 0x0001FE00) >> 9)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, - 0x40 | cmd_idx); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, - (u8) (arg >> 24)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, - (u8) (arg >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, - (u8) (arg >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); - rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - retval = rts51x_send_cmd(chip, MODE_CDIR, 100); - if (retval != STATUS_SUCCESS) { - read_err = 1; - rts51x_ep0_write_register(chip, CARD_STOP, - SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - retval = - rts51x_transfer_data_rcc(chip, RCV_BULK_PIPE(chip), - data_buf, buf_len, use_sg, NULL, - 10000, STAGE_DI); - if (retval != STATUS_SUCCESS) { - read_err = 1; - rts51x_ep0_write_register(chip, CARD_STOP, - SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - retval = rts51x_get_rsp(chip, 1, 500); - if (CHECK_SD_TRANS_FAIL(chip, retval)) { - read_err = 1; - rts51x_ep0_write_register(chip, CARD_STOP, - SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - } else { - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - - if (standby) { - retval = rts51x_sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, - 0, SD_RSP_TYPE_R1b, NULL, 0, - 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, 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, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - - rts51x_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - rts51x_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - } - - if (standby || cmd12) - cmd13_checkbit = 1; - - 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) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - - return TRANSPORT_GOOD; - -SD_Execute_Read_Cmd_Failed: - sd_card->pre_cmd_err = 1; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (read_err) - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rts51x_release_sd_card(chip); - rts51x_do_rts51x_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - TRACE_RET(chip, TRANSPORT_FAILED); -} - -int ext_rts51x_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, - u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, - u8 rsp_code, u32 arg, u32 data_len, - void *data_buf, unsigned int buf_len, int use_sg) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, rsp_len; - int cmd13_checkbit = 0, write_err = 0; - u8 rsp_type; - u32 i; - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - sd_card->last_rsp_type = rsp_type; - - retval = rts51x_sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (standby) { - retval = rts51x_sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, 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, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - if (data_len <= 512) { - u8 *buf; - unsigned int offset = 0; - void *sg = NULL; - - buf = kmalloc(data_len, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - if (use_sg) - rts51x_access_sglist(buf, data_len, (void *)data_buf, - &sg, &offset, FROM_XFER_BUF); - else - memcpy(buf, data_buf, data_len); - - - if (data_len > 256) { - rts51x_init_cmd(chip); - for (i = 0; i < 256; i++) { - rts51x_add_cmd(chip, WRITE_REG_CMD, - (u16) (PPBUF_BASE2 + i), 0xFF, - buf[i]); - } - retval = rts51x_send_cmd(chip, MODE_C, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - rts51x_init_cmd(chip); - for (i = 256; i < data_len; i++) { - rts51x_add_cmd(chip, WRITE_REG_CMD, - (u16) (PPBUF_BASE2 + i), 0xFF, - buf[i]); - } - retval = rts51x_send_cmd(chip, MODE_C, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - } else { - rts51x_init_cmd(chip); - for (i = 0; i < data_len; i++) { - rts51x_add_cmd(chip, WRITE_REG_CMD, - (u16) (PPBUF_BASE2 + i), 0xFF, - buf[i]); - } - retval = rts51x_send_cmd(chip, MODE_C, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - } - - kfree(buf); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, - (u8) ((data_len >> 8) & 0x03)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, - (u8) data_len); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x01); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - retval = rts51x_get_rsp(chip, 1, 250); - if (CHECK_SD_TRANS_FAIL(chip, retval)) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } else if (!(data_len & 0x1FF)) { - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, - 0xFF, (u8) (data_len >> 17)); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, - 0xFF, (u8) ((data_len & 0x0001FE00) >> 9)); - - rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDOR, 100); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - retval = - rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), - data_buf, buf_len, use_sg, NULL, - 10000, STAGE_DO); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - retval = rts51x_get_rsp(chip, 1, 10000); - if (CHECK_SD_TRANS_FAIL(chip, retval)) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - } else { - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (retval < 0) { - write_err = 1; - rts51x_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (standby) { - retval = rts51x_sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, - 0, SD_RSP_TYPE_R1b, NULL, 0, - 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, 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, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - rts51x_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - rts51x_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - } - - if (cmd12 || standby) { - /* There is CMD7 or CMD12 sent before CMD13 */ - cmd13_checkbit = 1; - } - - 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) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - return TRANSPORT_GOOD; - -SD_Execute_Write_Cmd_Failed: - sd_card->pre_cmd_err = 1; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (write_err) - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - rts51x_release_sd_card(chip); - rts51x_do_rts51x_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - TRACE_RET(chip, TRANSPORT_FAILED); -} - -int rts51x_sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_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, /* Version Number */ - 0x00, /* WP | Media Type */ - 0x00, /* RCA (Low byte) */ - 0x00, /* RCA (High byte) */ - 0x53, /* 'S' */ - 0x44, /* 'D' */ - 0x20, /* ' ' */ - 0x43, /* 'C' */ - 0x61, /* 'a' */ - 0x72, /* 'r' */ - 0x64, /* 'd' */ - 0x00, /* Max LUN Number */ - 0x00, - 0x00, - }; - - sd_card->pre_cmd_err = 0; - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) - || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) - || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) - || (0x64 != srb->cmnd[8])) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, 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: - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - /* 0x01:SD Memory Card; 0x02:Other Media; 0x03:Illegal Media; */ - buf[5] = (1 == CHK_SD(sd_card)) ? 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(unsigned, 18, scsi_bufflen(srb)); - rts51x_set_xfer_buf(buf, len, srb); - - return TRANSPORT_GOOD; -} - -int rts51x_sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 cmd_idx, rsp_code; - u8 standby = 0, acmd = 0; - u32 arg; - - if (!sd_card->sd_pass_thru_en) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x02) - standby = 1; - if (srb->cmnd[1] & 0x01) - acmd = 1; - - arg = ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | - ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; - - rsp_code = srb->cmnd[10]; - - retval = - ext_rts51x_sd_execute_no_data(chip, lun, cmd_idx, standby, acmd, rsp_code, - arg); - scsi_set_resid(srb, 0); - return retval; -} - -int rts51x_sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - unsigned int lun = SCSI_LUN(srb); - u8 cmd_idx, rsp_code, send_cmd12 = 0, standby = 0, acmd = 0; - u32 arg, data_len; - - if (!sd_card->sd_pass_thru_en) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = 1; - if (srb->cmnd[1] & 0x02) - standby = 1; - if (srb->cmnd[1] & 0x01) - acmd = 1; - - arg = ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | - ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; - - data_len = - ((u32) srb->cmnd[7] << 16) | ((u32) srb->cmnd[8] << 8) | - srb->cmnd[9]; - rsp_code = srb->cmnd[10]; - - retval = - ext_rts51x_sd_execute_read_data(chip, lun, cmd_idx, send_cmd12, standby, - acmd, rsp_code, arg, data_len, - scsi_sglist(srb), scsi_bufflen(srb), - scsi_sg_count(srb)); - scsi_set_resid(srb, 0); - return retval; -} - -int rts51x_sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - unsigned int lun = SCSI_LUN(srb); - u8 cmd_idx, rsp_code, send_cmd12 = 0, standby = 0, acmd = 0; - u32 data_len, arg; - - if (!sd_card->sd_pass_thru_en) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = 1; - if (srb->cmnd[1] & 0x02) - standby = 1; - if (srb->cmnd[1] & 0x01) - acmd = 1; - - 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]; - rsp_code = srb->cmnd[10]; - - retval = - ext_rts51x_sd_execute_write_data(chip, lun, cmd_idx, send_cmd12, standby, - acmd, rsp_code, arg, data_len, - scsi_sglist(srb), scsi_bufflen(srb), - scsi_sg_count(srb)); - scsi_set_resid(srb, 0); - return retval; -} - -int rts51x_sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - data_len = ((u16) srb->cmnd[7] << 8) | srb->cmnd[8]; - - if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, 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; - } - rts51x_set_xfer_buf(sd_card->rsp, count, srb); - - RTS51X_DEBUGP("Response length: %d\n", data_len); - RTS51X_DEBUGP("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 rts51x_sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_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) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) - || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) - || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) - || (0x64 != srb->cmnd[8])) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - switch (srb->cmnd[1] & 0x0F) { - case 0: - /* SD Card Power Off -> ON and Initialization */ - retval = rts51x_reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case 1: - /* reset CMD(CMD0) and Initialization - * (without SD Card Power Off -> ON) */ - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - default: - rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif diff --git a/drivers/staging/rts5139/sd_cprm.h b/drivers/staging/rts5139/sd_cprm.h deleted file mode 100644 index 79dfd27db41a..000000000000 --- a/drivers/staging/rts5139/sd_cprm.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_SD_CPRM_H -#define __RTS51X_SD_CPRM_H - -#include "rts51x_chip.h" -#include "sd.h" - -#ifdef SUPPORT_CPRM -int ext_rts51x_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, - u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code, - u32 arg); -int ext_rts51x_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, - u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, - u8 rsp_code, u32 arg, u32 data_len, void *data_buf, - unsigned int buf_len, int use_sg); -int ext_rts51x_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, - u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, - u8 rsp_code, u32 arg, u32 data_len, - void *data_buf, unsigned int buf_len, int use_sg); - -int rts51x_sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int rts51x_sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip); -#endif - -#endif /* __RTS51X_SD_CPRM_H */ diff --git a/drivers/staging/rts5139/trace.h b/drivers/staging/rts5139/trace.h deleted file mode 100644 index ac58b452ecb8..000000000000 --- a/drivers/staging/rts5139/trace.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_TRACE_H -#define __RTS51X_TRACE_H - -#include - -#include "debug.h" - -#define _MSG_TRACE - -#ifdef _MSG_TRACE -#define TRACE_RET(chip, ret) \ -do { \ - const char *_file = kbasename(__FILE__); \ - RTS51X_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ - (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].func, \ - __func__, MSG_FUNC_LEN-1); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].file, \ - _file, MSG_FILE_LEN-1); \ - get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf,\ - TIME_VAL_LEN); \ - (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ - (chip)->msg_idx++; \ - if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ - (chip)->msg_idx = 0; \ - } \ - return ret; \ -} while (0) - -#define TRACE_GOTO(chip, label) \ -do { \ - const char *_file = kbasename(__FILE__); \ - RTS51X_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ - (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].func, \ - __func__, MSG_FUNC_LEN-1); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].file, \ - _file, MSG_FILE_LEN-1); \ - get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf,\ - TIME_VAL_LEN); \ - (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ - (chip)->msg_idx++; \ - if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ - (chip)->msg_idx = 0; \ - } \ - goto label; \ -} while (0) -#else -#define TRACE_RET(chip, ret) return (ret) -#define TRACE_GOTO(chip, label) goto label -#endif - -#ifdef CONFIG_RTS5139_DEBUG -#define RTS51X_DUMP(buf, buf_len) \ - print_hex_dump(KERN_DEBUG, RTS51X_TIP, DUMP_PREFIX_NONE, \ - 16, 1, (buf), (buf_len), false) - -#define CATCH_TRIGGER(chip) \ -do { \ - rts51x_ep0_write_register((chip), 0xFC31, 0x01, 0x01); \ - RTS51X_DEBUGP("Catch trigger!\n"); \ -} while (0) - -#else -#define RTS51X_DUMP(buf, buf_len) -#define CATCH_TRIGGER(chip) -#endif - -#endif /* __RTS51X_TRACE_H */ diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c deleted file mode 100644 index be432351be86..000000000000 --- a/drivers/staging/rts5139/xd.c +++ /dev/null @@ -1,2145 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include "debug.h" -#include "trace.h" -#include "rts51x.h" -#include "rts51x_transport.h" -#include "rts51x_scsi.h" -#include "rts51x_card.h" -#include "xd.h" - -static int xd_build_l2p_tbl(struct rts51x_chip *chip, int zone_no); -static int xd_init_page(struct rts51x_chip *chip, u32 phy_blk, u16 logoff, - u8 start_page, u8 end_page); - -static inline void xd_set_err_code(struct rts51x_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 rts51x_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) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int xd_switch_clock(struct rts51x_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - - retval = rts51x_select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int xd_read_id(struct rts51x_chip *chip, u8 id_cmd, u8 *id_buf, - u8 buf_len) -{ - int retval, i; - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_ID); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - for (i = 0; i < 4; i++) { - rts51x_add_cmd(chip, READ_REG_CMD, (u16) (XD_ADDRESS1 + i), 0, - 0); - } - - retval = rts51x_send_cmd(chip, MODE_CR, 20); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 5, 20); - - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, retval); - } - - if (id_buf && buf_len) { - if (buf_len > 4) - buf_len = 4; - rts51x_read_rsp_buf(chip, 1, id_buf, buf_len); - } - - return STATUS_SUCCESS; -} - -static void xd_assign_phy_addr(struct rts51x_chip *chip, u32 addr, u8 mode) -{ - struct xd_info *xd_card = &(chip->xd_card); - - switch (mode) { - case XD_RW_ADDR: - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, - (u8) addr); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, - (u8) (addr >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, 0xFF, - (u8) (addr >> 16)); - rts51x_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: - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, - (u8) addr); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, - (u8) (addr >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, - (u8) (addr >> 16)); - rts51x_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 rts51x_chip *chip, u32 page_addr, u8 *buf, - int buf_len) -{ - int retval, i; - - rts51x_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_REDUNDANT); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - for (i = 0; i < 6; i++) { - rts51x_add_cmd(chip, READ_REG_CMD, (u16) (XD_PAGE_STATUS + i), - 0, 0); - } - for (i = 0; i < 4; i++) { - rts51x_add_cmd(chip, READ_REG_CMD, (u16) (XD_RESERVED0 + i), 0, - 0); - } - rts51x_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 11, 500); - - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, retval); - } - - if (buf && buf_len) { - if (buf_len > 11) - buf_len = 11; - rts51x_read_rsp_buf(chip, 1, buf, buf_len); - } - - return STATUS_SUCCESS; -} - -static int xd_read_data_from_ppb(struct rts51x_chip *chip, int offset, u8 *buf, - int buf_len) -{ - int retval, i; - - if (!buf || (buf_len <= 0)) - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - - for (i = 0; i < buf_len; i++) { - rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, 0, - 0); - } - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, buf_len, 200); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - rts51x_read_rsp_buf(chip, 0, buf, buf_len); - - return STATUS_SUCCESS; -} - -static int xd_read_cis(struct rts51x_chip *chip, u32 page_addr, u8 *buf, - int buf_len) -{ - int retval; - u8 reg; - - if (!buf || (buf_len < 10)) - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END | XD_PPB_EMPTY, - XD_TRANSFER_END | XD_PPB_EMPTY); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 1, 500); - if (retval == STATUS_TIMEDOUT) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, retval); - } - - RTS51X_READ_REG(chip, XD_PAGE_STATUS, ®); - if (reg != XD_GPG) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - RTS51X_READ_REG(chip, XD_CTL, ®); - - if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { - retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (reg & XD_ECC1_ERROR) { /* correctable error */ - u8 ecc_bit, ecc_byte; - - RTS51X_READ_REG(chip, XD_ECC_BIT1, &ecc_bit); - RTS51X_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte); - - RTS51X_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", - ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - RTS51X_DEBUGP("Before correct: 0x%x\n", - buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - RTS51X_DEBUGP("After correct: 0x%x\n", - buf[ecc_byte]); - } - } - } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) { - RTS51X_WRITE_REG(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, - XD_STOP | XD_CLR_ERR); - - retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (reg & XD_ECC2_ERROR) { - u8 ecc_bit, ecc_byte; - - RTS51X_READ_REG(chip, XD_ECC_BIT2, &ecc_bit); - RTS51X_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte); - - RTS51X_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", - ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - RTS51X_DEBUGP("Before correct: 0x%x\n", - buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - RTS51X_DEBUGP("After correct: 0x%x\n", - buf[ecc_byte]); - } - } - } else { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static void xd_pull_ctl_disable(struct rts51x_chip *chip) -{ - if (CHECK_PKG(chip, LQFP48)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); - } -} - -static void xd_pull_ctl_enable(struct rts51x_chip *chip) -{ - if (CHECK_PKG(chip, LQFP48)) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA5); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x59); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); - } -} - -static int reset_xd(struct rts51x_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval, i, j; - u8 id_buf[4], redunt[11]; - - retval = rts51x_select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, - XD_PGSTS_NOT_FF); - if (chip->asic_code) - xd_pull_ctl_disable(chip); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3)); - - if (!chip->option.FT2_fast_mode) { - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_INIT, XD_NO_AUTO_PWR_OFF, - 0); - if (CHECK_PKG(chip, LQFP48) || - chip->option.rts5129_D3318_off_enable) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, - DV3318_AUTO_PWR_OFF, - DV3318_AUTO_PWR_OFF); - } - } - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); - if (!chip->option.FT2_fast_mode) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - } - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - if (!chip->option.FT2_fast_mode) { -#ifdef SD_XD_IO_FOLLOW_PWR - if (CHECK_PKG(chip, LQFP48) - || chip->option.rts5129_D3318_off_enable) { - rts51x_write_register(chip, CARD_PWR_CTL, - LDO_OFF, LDO_OFF); - } -#endif - - wait_timeout(250); - -#ifdef SD_XD_IO_FOLLOW_PWR - if (CHECK_PKG(chip, LQFP48) - || chip->option.rts5129_D3318_off_enable) { - rts51x_init_cmd(chip); - if (chip->asic_code) { - xd_pull_ctl_enable(chip); - } else { - rts51x_add_cmd(chip, WRITE_REG_CMD, - FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & - FPGA_XD_PULL_CTL_EN2)); - } - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } -#endif - - retval = rts51x_card_power_on(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); -#ifdef SUPPORT_OCP - wait_timeout(50); - rts51x_get_card_status(chip, &(chip->card_status)); - chip->ocp_stat = (chip->card_status >> 4) & 0x03; - - if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { - RTS51X_DEBUGP("Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - - rts51x_init_cmd(chip); - - if (chip->asic_code) - xd_pull_ctl_enable(chip); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2)); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, - XD_OUTPUT_EN); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!chip->option.FT2_fast_mode) - wait_timeout(200); - - retval = xd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - /* Read ID to check if the timing setting is right */ - for (i = 0; i < 4; i++) { - u8 xd_dat, xd_ctl; - - if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, - XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * - (2 + i + chip->option.rts51x_xd_rw_step) - + XD_TIME_RWN_STEP * - (i + chip->option.rts51x_xd_rwn_step)); - rts51x_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)); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_RESET); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - rts51x_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rts51x_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, retval); - } - - retval = rts51x_get_rsp(chip, 3, 100); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, retval); - } - - xd_dat = chip->rsp_buf[1]; - xd_ctl = chip->rsp_buf[2]; - RTS51X_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", xd_dat, xd_ctl); - - if (((xd_dat & READY_FLAG) != READY_STATE) - || !(xd_ctl & XD_RDY)) - continue; - - retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - RTS51X_DEBUGP("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]; - - switch (xd_card->device_code) { - case XD_4M_X8_512_1: - case XD_4M_X8_512_2: - xd_card->block_shift = 4; /* 16 pages per block */ - xd_card->page_off = 0x0F; - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 8000; /* 500 * 2 ^ 4 */ - 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; /* 1000 * 2 ^ 4 */ - break; - case XD_16M_X8_512: - XD_PAGE_512(xd_card); /* 32 pages per block */ - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 32000; /* 1000 * 2 ^ 5 */ - 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; /* 2000 * 2 ^ 5 */ - 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; /* 4000 * 2 ^ 5 */ - 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; /* 8000 * 2 ^ 5 */ - 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; /* 16000 * 2 ^ 5 */ - break; - case XD_512M_X8: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 32; - xd_card->capacity = 1024000; /* 32000 * 2 ^ 5 */ - 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; /* 64000 * 2 ^ 5 */ - 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; /* 128000 * 2 ^ 5 */ - 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) - TRACE_RET(chip, retval); - - if (id_buf[1] != xd_card->device_code) - break; - } - - /* Current timing pass */ - 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; - - TRACE_RET(chip, STATUS_FAIL); - } - - retval = xd_read_id(chip, READ_xD_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - RTS51X_DEBUGP("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) - TRACE_RET(chip, STATUS_FAIL); - - /* Search CIS block */ - for (i = 0; i < 24; i++) { - u32 page_addr; - - if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) - TRACE_RET(chip, 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; - /* Check page status */ - 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; - } - - 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) - TRACE_RET(chip, retval); - - 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; - } - - RTS51X_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block); - if (xd_card->cis_block == 0xFFFF) - TRACE_RET(chip, 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 rts51x_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int size, i; - - RTS51X_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt); - - if (xd_card->zone_cnt < 1) - TRACE_RET(chip, STATUS_FAIL); - - size = xd_card->zone_cnt * sizeof(struct zone_entry); - RTS51X_DEBUGP("Buffer size for l2p table is %d\n", size); - - xd_card->zone = vmalloc(size); - if (!xd_card->zone) - TRACE_RET(chip, STATUS_NOMEM); - - 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) -{ - RTS51X_DEBUGP("free_zone\n"); - if (!zone) - return; - zone->build_flag = 0; - zone->set_index = 0; - zone->get_index = 0; - zone->unused_blk_cnt = 0; - if (zone->l2p_table) { - vfree(zone->l2p_table); - zone->l2p_table = NULL; - } - if (zone->free_table) { - vfree(zone->free_table); - zone->free_table = NULL; - } -} - -static void xd_set_unused_block(struct rts51x_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) { - RTS51X_DEBUGP("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 == NULL) { - 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); - RTS51X_DEBUGP("Set unused block fail, invalid set_index\n"); - return; - } - - RTS51X_DEBUGP("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 rts51x_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) { - RTS51X_DEBUGP("Get unused block from invalid zone" - "(zone_no = %d, zone_cnt = %d)\n", - zone_no, xd_card->zone_cnt); - TRACE_RET(chip, BLK_NOT_FOUND); - } - zone = &(xd_card->zone[zone_no]); - - if ((zone->unused_blk_cnt == 0) || - (zone->set_index == zone->get_index)) { - free_zone(zone); - RTS51X_DEBUGP("Get unused block fail," - "no unused block available\n"); - TRACE_RET(chip, BLK_NOT_FOUND); - } - if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) { - free_zone(zone); - RTS51X_DEBUGP("Get unused block fail, invalid get_index\n"); - TRACE_RET(chip, BLK_NOT_FOUND); - } - - RTS51X_DEBUGP("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 rts51x_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 int xd_delay_write(struct rts51x_chip *chip); - -static u32 xd_get_l2p_tbl(struct rts51x_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; - - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - RTS51X_DEBUGP("In xd_get_l2p_tbl," - "delay write fail!\n"); - TRACE_RET(chip, BLK_NOT_FOUND); - } - - if (zone->unused_blk_cnt <= 0) { - RTS51X_DEBUGP("No unused block!\n"); - TRACE_RET(chip, 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) { - RTS51X_DEBUGP("No unused block available!\n"); - TRACE_RET(chip, 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) { - RTS51X_DEBUGP("No good unused block available!\n"); - TRACE_RET(chip, 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 rts51x_reset_xd_card(struct rts51x_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; - - rts51x_enable_card_clock(chip, XD_CARD); - - retval = reset_xd(chip); - if (retval != STATUS_SUCCESS) { - if (chip->option.reset_or_rw_fail_set_pad_drive) { - rts51x_write_register(chip, CARD_DRIVE_SEL, - SD20_DRIVE_MASK, DRIVE_8mA); - } - TRACE_RET(chip, retval); - } - - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -static int xd_mark_bad_block(struct rts51x_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - u32 page_addr; - u8 reg = 0; - - RTS51X_DEBUGP("mark block 0x%x as bad block\n", phy_blk); - - if (phy_blk == BLK_NOT_FOUND) - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, - XD_LATER_BBLK); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF); - rts51x_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); - - /* Specify page count */ - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, - xd_card->page_off + 1); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rts51x_get_rsp(chip, 1, 100); - - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - rts51x_ep0_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); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int xd_init_page(struct rts51x_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; - - RTS51X_DEBUGP("Init block 0x%x\n", phy_blk); - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - if (phy_blk == BLK_NOT_FOUND) - TRACE_RET(chip, STATUS_FAIL); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, - (u8) (logoff >> 8)); - rts51x_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); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, - XD_BA_TRANSFORM); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, - (end_page - start_page)); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rts51x_get_rsp(chip, 1, 500); - - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - rts51x_ep0_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); - } - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int xd_copy_page(struct rts51x_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; - - RTS51X_DEBUGP("Copy page from block 0x%x to block 0x%x\n", old_blk, - new_blk); - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - - if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) - TRACE_RET(chip, 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); - - RTS51X_WRITE_REG(chip, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - for (i = start_page; i < end_page; i++) { - if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { - RTS51X_WRITE_REG(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, - XD_STOP | XD_CLR_ERR); - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - rts51x_init_cmd(chip); - - xd_assign_phy_addr(chip, old_page, XD_RW_ADDR); - - /* Single page read */ - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR | STAGE_XD_STATUS, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 4, 500); - if ((retval != STATUS_SUCCESS) || - (chip->rsp_buf[2] & (XD_ECC1_ERROR | XD_ECC2_ERROR))) { - rts51x_clear_xd_error(chip); - reg = 0; - rts51x_ep0_read_register(chip, XD_CTL, ®); - if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) { - wait_timeout(100); - - if (monitor_card_cd(chip, XD_CARD) == - CD_NOT_EXIST) { - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - if (((reg & - (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) - == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) - || ((reg & (XD_ECC2_ERROR | - XD_ECC2_UNCORRECTABLE)) == - (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { - RTS51X_WRITE_REG(chip, XD_PAGE_STATUS, - 0xFF, XD_BPG); - RTS51X_WRITE_REG(chip, XD_BLOCK_STATUS, - 0xFF, XD_GBLK); - XD_SET_BAD_OLDBLK(xd_card); - RTS51X_DEBUGP("old block 0x%x" - "ecc error\n", old_blk); - } - } else { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - if (XD_CHK_BAD_OLDBLK(xd_card)) - rts51x_clear_xd_error(chip); - - rts51x_init_cmd(chip); - - xd_assign_phy_addr(chip, new_page, XD_RW_ADDR); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_PAGES); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 1, 300); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - reg = 0; - rts51x_ep0_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); - } - TRACE_RET(chip, retval); - } - - old_page++; - new_page++; - } - - return STATUS_SUCCESS; -} - -static int xd_reset_cmd(struct rts51x_chip *chip) -{ - int retval; - u8 xd_dat, xd_ctl; - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_RESET); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - rts51x_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rts51x_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 3, 100); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, retval); - } - - xd_dat = chip->rsp_buf[1]; - xd_ctl = chip->rsp_buf[2]; - if (((xd_dat & READY_FLAG) == READY_STATE) && (xd_ctl & XD_RDY)) - return STATUS_SUCCESS; - - TRACE_RET(chip, STATUS_FAIL); -} - -static int xd_erase_block(struct rts51x_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &(chip->xd_card); - u32 page_addr; - u8 reg = 0, xd_dat; - int i, retval; - - if (phy_blk == BLK_NOT_FOUND) - TRACE_RET(chip, STATUS_FAIL); - - page_addr = phy_blk << xd_card->block_shift; - - for (i = 0; i < 3; i++) { - rts51x_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_ERASE); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - rts51x_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 2, 300); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - rts51x_ep0_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } else { - xd_set_err_code(chip, XD_ERASE_FAIL); - } - retval = xd_reset_cmd(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - continue; - } - xd_dat = chip->rsp_buf[1]; - if (xd_dat & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; - } - - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_ERASE_FAIL); - TRACE_RET(chip, STATUS_FAIL); -} - -static int xd_build_l2p_tbl(struct rts51x_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, cur_lst_page_logoff, - ent_lst_page_logoff; - u8 redunt[11]; - - RTS51X_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no); - - if (xd_card->zone == NULL) { - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - if (xd_card->zone[zone_no].build_flag) { - RTS51X_DEBUGP("l2p table of zone %d has been built\n", - zone_no); - return STATUS_SUCCESS; - } - - zone = &(xd_card->zone[zone_no]); - - if (zone->l2p_table == NULL) { - zone->l2p_table = vmalloc(2000); - if (zone->l2p_table == NULL) - TRACE_GOTO(chip, Build_Fail); - } - memset((u8 *) (zone->l2p_table), 0xff, 2000); - - if (zone->free_table == NULL) { - zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2); - if (zone->free_table == NULL) - TRACE_GOTO(chip, 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; - } - - RTS51X_DEBUGP("start block 0x%x, end block 0x%x\n", start, end); - - zone->set_index = 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) { - RTS51X_DEBUGP("bad block\n"); - continue; - } - - if (xd_check_data_blank(redunt)) { - RTS51X_DEBUGP("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++; - } - - RTS51X_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i); - RTS51X_DEBUGP("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: - if (zone->l2p_table) { - vfree(zone->l2p_table); - zone->l2p_table = NULL; - } - if (zone->free_table) { - vfree(zone->free_table); - zone->free_table = NULL; - } - - return STATUS_FAIL; -} - -static int xd_send_cmd(struct rts51x_chip *chip, u8 cmd) -{ - int retval; - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_SET_CMD); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = rts51x_get_rsp(chip, 1, 200); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int xd_read_multiple_pages(struct rts51x_chip *chip, u32 phy_blk, - u32 log_blk, u8 start_page, u8 end_page, - u8 *buf, void **ptr, 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) - TRACE_RET(chip, 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 (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - page_addr = (phy_blk << xd_card->block_shift) + start_page; - - rts51x_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, - XD_PPB_TO_SIE); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - RING_BUFFER); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - rts51x_trans_dma_enable(chip->srb->sc_data_direction, chip, - page_cnt * 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END | XD_PPB_EMPTY, - XD_TRANSFER_END | XD_PPB_EMPTY); - - retval = rts51x_send_cmd(chip, MODE_CDIR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - rts51x_transfer_data_partial(chip, RCV_BULK_PIPE(chip), (void *)buf, - ptr, offset, page_cnt * 512, - scsi_sg_count(chip->srb), NULL, 2000); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - - if (retval == STATUS_TIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, retval); - } else { - TRACE_GOTO(chip, Fail); - } - } - retval = rts51x_get_rsp(chip, 1, 200); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - - if (retval == STATUS_TIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, retval); - } else { - TRACE_GOTO(chip, Fail); - } - } - - return STATUS_SUCCESS; - -Fail: - rts51x_ep0_read_register(chip, XD_PAGE_STATUS, ®_val); - RTS51X_DEBUGP("XD_PAGE_STATUS: 0x%x\n", reg_val); - - if (reg_val != XD_GPG) - xd_set_err_code(chip, XD_PRG_ERROR); - - rts51x_ep0_read_register(chip, XD_CTL, ®_val); - RTS51X_DEBUGP("XD_CTL: 0x%x\n", reg_val); - - /* Handle uncorrectable ECC error */ - 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 (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, 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); - TRACE_RET(chip, 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); - TRACE_RET(chip, 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); - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int xd_finish_write(struct rts51x_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; - - RTS51X_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x," - "log_blk = 0x%x\n", old_blk, new_blk, log_blk); - - if (page_off > xd_card->page_off) - TRACE_RET(chip, 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); - TRACE_RET(chip, 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); - TRACE_RET(chip, 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 { - /* Add source block to unused block */ - xd_set_unused_block(chip, old_blk); - } - } else { - xd_set_err_code(chip, XD_NO_ERROR); - XD_CLR_BAD_OLDBLK(xd_card); - } - } - - /* Add target block to L2P table */ - xd_set_l2p_tbl(chip, zone_no, log_off, (u16) (new_blk & 0x3FF)); - - return STATUS_SUCCESS; -} - -static int xd_prepare_write(struct rts51x_chip *chip, - u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) -{ - int retval; - - RTS51X_DEBUGP("xd_prepare_write, old_blk = 0x%x, new_blk = 0x%x," - "log_blk = 0x%x, page_off = %d\n", - 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) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -static int xd_write_multiple_pages(struct rts51x_chip *chip, u32 old_blk, - u32 new_blk, u32 log_blk, u8 start_page, - u8 end_page, u8 *buf, void **ptr, - 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; - - RTS51X_DEBUGP("xd_write_multiple_pages, old_blk = 0x%x," - "new_blk = 0x%x, log_blk = 0x%x\n", - old_blk, new_blk, log_blk); - - if (start_page > end_page) - TRACE_RET(chip, 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; - - /* Send index command */ - retval = xd_send_cmd(chip, READ1_1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - rts51x_init_cmd(chip); - - /* Prepare redundant field */ - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, - (u8) (log_off >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, - (u8) log_off); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - /* Transform the block address by hardware */ - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, - XD_BA_TRANSFORM); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - RING_BUFFER); - - rts51x_trans_dma_enable(chip->srb->sc_data_direction, chip, - page_cnt * 512, DMA_512); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_PAGES); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CDOR, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - retval = - rts51x_transfer_data_partial(chip, SND_BULK_PIPE(chip), (void *)buf, - ptr, offset, page_cnt * 512, - scsi_sg_count(chip->srb), NULL, 2000); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - - if (retval == STATUS_TIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, retval); - } else { - TRACE_GOTO(chip, Fail); - } - } - retval = rts51x_get_rsp(chip, 1, 200); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - - if (retval == STATUS_TIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, retval); - } else { - TRACE_GOTO(chip, 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: - rts51x_ep0_read_register(chip, XD_DAT, ®_val); - RTS51X_DEBUGP("XD_DAT: 0x%x\n", reg_val); - - if (reg_val & PROGRAM_ERROR) { - xd_set_err_code(chip, XD_PRG_ERROR); - xd_mark_bad_block(chip, new_blk); - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int xd_delay_write(struct rts51x_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) { - RTS51X_DEBUGP("xd_delay_write\n"); - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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) - TRACE_RET(chip, retval); - } - - return STATUS_SUCCESS; -} - -int rts51x_xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, - u32 start_sector, u16 sector_cnt) -{ - struct xd_info *xd_card = &(chip->xd_card); - unsigned int lun = SCSI_LUN(srb); - struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); - int retval, zone_no; - 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 *buf; - void *ptr = NULL; - unsigned int offset = 0; - - xd_set_err_code(chip, XD_NO_ERROR); - - xd_card->counter = 0; - - RTS51X_DEBUGP("rts51x_xd_rw: scsi_bufflen = %d, scsi_sg_count = %d\n", - scsi_bufflen(srb), scsi_sg_count(srb)); - RTS51X_DEBUGP("Data direction: %s\n", - (srb->sc_data_direction == - DMA_TO_DEVICE) ? "write" : "read"); - - buf = (u8 *) scsi_sglist(srb); - - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - 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); - - RTS51X_DEBUGP("log_blk = 0x%x\n", log_blk); - - 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; - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, retval); - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - 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) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, retval); - } - } - 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) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, retval); - } - 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)) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, retval); - } - - retval = - xd_prepare_write(chip, old_blk, new_blk, log_blk, - start_page); - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, XD_CARD) == - CD_NOT_EXIST) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, retval); - } - } - } else { - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, retval); - } - - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - if (old_blk == BLK_NOT_FOUND) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTS51X_DEBUGP("old_blk = 0x%x\n", old_blk); - if (srb->sc_data_direction == DMA_TO_DEVICE) - RTS51X_DEBUGP("new_blk = 0x%x\n", new_blk); - - while (total_sec_cnt) { - 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, - buf, &ptr, &offset); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - retval = - xd_write_multiple_pages(chip, old_blk, new_blk, - log_blk, start_page, - end_page, buf, &ptr, - &offset); - if (retval != STATUS_SUCCESS) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - total_sec_cnt -= page_cnt; - - 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; - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, retval); - } - } - - 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) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } else { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - } - TRACE_RET(chip, 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) { - rts51x_set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - start_page = 0; - } - - if ((srb->sc_data_direction == DMA_TO_DEVICE) && - (end_page != (xd_card->page_off + 1))) { - 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; - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -void rts51x_xd_free_l2p_tbl(struct rts51x_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int i = 0; - - if (xd_card->zone != NULL) { - for (i = 0; i < xd_card->zone_cnt; i++) { - if (xd_card->zone[i].l2p_table != NULL) { - vfree(xd_card->zone[i].l2p_table); - xd_card->zone[i].l2p_table = NULL; - } - if (xd_card->zone[i].free_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 rts51x_xd_cleanup_work(struct rts51x_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - - if (xd_card->delay_write.delay_write_flag) { - RTS51X_DEBUGP("xD: delay write\n"); - xd_delay_write(chip); - xd_card->counter = 0; - } -} - -static int xd_power_off_card3v3(struct rts51x_chip *chip) -{ - int retval; - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, XD_CLK_EN, 0); - - if (chip->asic_code) - xd_pull_ctl_disable(chip); - else - rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, 0xDF); - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); - if (!chip->option.FT2_fast_mode) { - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, - POWER_OFF); - if (CHECK_PKG(chip, LQFP48) - || chip->option.rts5129_D3318_off_enable) - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, - DV3318_AUTO_PWR_OFF, 0); - } - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} - -int rts51x_release_xd_card(struct rts51x_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - - RTS51X_DEBUGP("rts51x_release_xd_card\n"); - - chip->card_ready &= ~XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->card_wp &= ~XD_CARD; - - xd_card->delay_write.delay_write_flag = 0; - - rts51x_xd_free_l2p_tbl(chip); - - rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); - - retval = xd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (chip->asic_code && CHECK_PKG(chip, QFN24)) - wait_timeout(20); - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5139/xd.h b/drivers/staging/rts5139/xd.h deleted file mode 100644 index 695a0b4d7e52..000000000000 --- a/drivers/staging/rts5139/xd.h +++ /dev/null @@ -1,191 +0,0 @@ -/* Driver for Realtek RTS51xx USB card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_XD_H -#define __RTS51X_XD_H - -/* 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 for XD Status */ -#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 for device code */ -#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 - -/* Assign address mode */ -#define XD_RW_ADDR 0x01 -#define XD_ERASE_ADDR 0x02 - -/* Macro Definition */ -#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) - -/* Offset in xD redundant buffer */ -#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 - -/* For CIS block */ -#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 rts51x_reset_xd_card(struct rts51x_chip *chip); -int rts51x_xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, - u16 sector_cnt); -void rts51x_xd_free_l2p_tbl(struct rts51x_chip *chip); -void rts51x_xd_cleanup_work(struct rts51x_chip *chip); -int rts51x_release_xd_card(struct rts51x_chip *chip); - -#endif /* __RTS51X_XD_H */ -- 2.30.2