diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-08 11:31:16 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-08 11:31:16 -0700 |
commit | 3f17ea6dea8ba5668873afa54628a91aaa3fb1c0 (patch) | |
tree | afbeb2accd4c2199ddd705ae943995b143a0af02 /drivers/staging/rts5139 | |
parent | 1860e379875dfe7271c649058aeddffe5afd9d0d (diff) | |
parent | 1a5700bc2d10cd379a795fd2bb377a190af5acd4 (diff) |
Merge branch 'next' (accumulated 3.16 merge window patches) into master
Now that 3.15 is released, this merges the 'next' branch into 'master',
bringing us to the normal situation where my 'master' branch is the
merge window.
* accumulated work in next: (6809 commits)
ufs: sb mutex merge + mutex_destroy
powerpc: update comments for generic idle conversion
cris: update comments for generic idle conversion
idle: remove cpu_idle() forward declarations
nbd: zero from and len fields in NBD_CMD_DISCONNECT.
mm: convert some level-less printks to pr_*
MAINTAINERS: adi-buildroot-devel is moderated
MAINTAINERS: add linux-api for review of API/ABI changes
mm/kmemleak-test.c: use pr_fmt for logging
fs/dlm/debug_fs.c: replace seq_printf by seq_puts
fs/dlm/lockspace.c: convert simple_str to kstr
fs/dlm/config.c: convert simple_str to kstr
mm: mark remap_file_pages() syscall as deprecated
mm: memcontrol: remove unnecessary memcg argument from soft limit functions
mm: memcontrol: clean up memcg zoneinfo lookup
mm/memblock.c: call kmemleak directly from memblock_(alloc|free)
mm/mempool.c: update the kmemleak stack trace for mempool allocations
lib/radix-tree.c: update the kmemleak stack trace for radix tree allocations
mm: introduce kmemleak_update_trace()
mm/kmemleak.c: use %u to print ->checksum
...
Diffstat (limited to 'drivers/staging/rts5139')
27 files changed, 0 insertions, 20471 deletions
diff --git a/drivers/staging/rts5139/Kconfig b/drivers/staging/rts5139/Kconfig deleted file mode 100644 index afd526bf422..00000000000 --- 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 75dd31224e6..00000000000 --- 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 <http://www.gnu.org/licenses/>. -# -# 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 dd5fabb8ea7..00000000000 --- 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 73dec133a1b..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/kernel.h> - -#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 390292ad456..00000000000 --- a/drivers/staging/rts5139/ms.c +++ /dev/null @@ -1,4185 +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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> - -#include "debug.h" -#include "trace.h" -#include "rts51x.h" -#include "rts51x_transport.h" -#include "rts51x_scsi.h" -#include "rts51x_card.h" -#include "ms.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; -} - -#ifdef SUPPORT_MAGIC_GATE -int mg_set_tpc_para_sub(struct rts51x_chip *chip, int type, u8 mg_entry_num); -#endif - -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 = 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 857c1974ef2..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 00862c1a36d..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/slab.h> - -#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 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 d15733a992a..00000000000 --- a/drivers/staging/rts5139/ms_mg.h +++ /dev/null @@ -1,41 +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 <http://www.gnu.org/licenses/>. - * - * 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_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 c8d06d4fddd..00000000000 --- a/drivers/staging/rts5139/rts51x.c +++ /dev/null @@ -1,857 +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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/workqueue.h> -#include <linux/errno.h> -#include <linux/freezer.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/utsname.h> -#include <linux/usb.h> - -#include <scsi/scsi.h> -#include <scsi/scsi_cmnd.h> -#include <scsi/scsi_device.h> -#include <scsi/scsi_devinfo.h> -#include <scsi/scsi_eh.h> -#include <scsi/scsi_host.h> - -#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) -{ - RTS51X_DEBUGP("Ready to enter SS state\n"); - usb_autopm_enable(chip->usb->pusb_intf); -} - -void rts51x_try_to_exit_ss(struct rts51x_chip *chip) -{ - RTS51X_DEBUGP("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); - - RTS51X_DEBUGP("%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) { - RTS51X_DEBUGP("Enter SS state"); - chip->resume_from_scsi = 0; - RTS51X_SET_STAT(chip, STAT_SS); - } else { - RTS51X_DEBUGP("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); - - RTS51X_DEBUGP("%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 */ - RTS51X_DEBUGP("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); - - RTS51X_DEBUGP("%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); - - RTS51X_DEBUGP("%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); - - RTS51X_DEBUGP("%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)) { - RTS51X_DEBUGP("-- 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); - RTS51X_DEBUGP("-- 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 SkipForAbort; - } - - scsi_unlock(host); - - /* reject the command if the direction indicator - * is UNKNOWN - */ - if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { - RTS51X_DEBUGP("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) { - RTS51X_DEBUGP("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) { - RTS51X_DEBUGP("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 -SkipForAbort : - RTS51X_DEBUGP("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)) { - RTS51X_DEBUGP("-- 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; - RTS51X_DEBUGP("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)); - RTS51X_DEBUGP("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 */ - RTS51X_DEBUGP("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) { - RTS51X_DEBUGP("usb_ctrlrequest allocation failed\n"); - 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) { - RTS51X_DEBUGP("I/O buffer allocation failed\n"); - 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) { - RTS51X_DEBUGP("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) { - RTS51X_DEBUGP("URB allocation failed\n"); - return -ENOMEM; - } - - rts51x->intr_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rts51x->intr_urb) { - RTS51X_DEBUGP("URB allocation failed\n"); - return -ENOMEM; - } - - chip->cmd_buf = 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) -{ - RTS51X_DEBUGP("-- %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. - */ - RTS51X_DEBUGP("-- 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; - - RTS51X_DEBUGP("-- %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; - - RTS51X_DEBUGP("%s detected\n", RTS51X_NAME); - - rts51x = kzalloc(sizeof(struct rts51x_usb), GFP_KERNEL); - if (!rts51x) { - printk(KERN_WARNING RTS51X_TIP - "Unable to allocate rts51x_usb\n"); - 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) { - printk(KERN_WARNING RTS51X_TIP - "Unable to allocate the scsi host\n"); - 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 BadDevice; - - /* Find the endpoints and calculate pipe values */ - result = get_pipes(chip); - if (result) - goto BadDevice; - - /* Acquire all the other resources and add the host */ - result = rts51x_acquire_resources(chip); - if (result) - goto BadDevice; - - /* Start up our control thread */ - th = kthread_run(rts51x_control_thread, chip, RTS51X_CTL_THREAD); - if (IS_ERR(th)) { - printk(KERN_WARNING RTS51X_TIP - "Unable to start control thread\n"); - result = PTR_ERR(th); - goto BadDevice; - } - rts51x->ctl_thread = th; - - result = scsi_add_host(rts51x_to_host(chip), &rts51x->pusb_intf->dev); - if (result) { - printk(KERN_WARNING RTS51X_TIP "Unable to add the scsi host\n"); - goto BadDevice; - } - 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)) { - printk(KERN_WARNING RTS51X_TIP - "Unable to start polling thread\n"); - result = PTR_ERR(th); - goto BadDevice; - } - 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); - RTS51X_DEBUGP("pm_usage_cnt = %d\n", GET_PM_USAGE_CNT(chip)); - } -#endif - - return 0; - - /* We come here if there are any problems */ -BadDevice: - RTS51X_DEBUGP("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); - - RTS51X_DEBUGP("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 ecc0109a5b1..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/usb.h> -#include <linux/usb_usual.h> -#include <linux/blkdev.h> -#include <linux/completion.h> -#include <linux/mutex.h> -#include <linux/cdrom.h> -#include <linux/kernel.h> - -#include <scsi/scsi.h> -#include <scsi/scsi_cmnd.h> -#include <scsi/scsi_device.h> -#include <scsi/scsi_devinfo.h> -#include <scsi/scsi_eh.h> -#include <scsi/scsi_host.h> - -#define 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 03456d9873e..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/workqueue.h> - -#include <scsi/scsi.h> -#include <scsi/scsi_eh.h> -#include <scsi/scsi_device.h> - -#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 df8816e0f84..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 7d7510de170..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/workqueue.h> - -#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 12deb24cfbb..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/usb.h> -#include <linux/usb_usual.h> -#include <linux/blkdev.h> -#include <linux/completion.h> -#include <linux/mutex.h> -#include <scsi/scsi_host.h> - -#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 677d18b3dcd..00000000000 --- a/drivers/staging/rts5139/rts51x_fop.c +++ /dev/null @@ -1,292 +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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/types.h> -#include <linux/stat.h> -#include <linux/kref.h> -#include <linux/slab.h> - -#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 c691ee99720..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/fs.h> -#include <linux/types.h> - -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 75282fea38f..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/export.h> - -#include <scsi/scsi.h> -#include <scsi/scsi_eh.h> -#include <scsi/scsi_device.h> - -#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 1a0d7056618..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/usb.h> -#include <linux/usb_usual.h> -#include <linux/blkdev.h> -#include <linux/completion.h> -#include <linux/mutex.h> -#include <scsi/scsi_host.h> - -#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 74588d249b3..00000000000 --- a/drivers/staging/rts5139/rts51x_transport.c +++ /dev/null @@ -1,736 +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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/slab.h> - -#include <scsi/scsi.h> -#include <scsi/scsi_eh.h> -#include <scsi/scsi_device.h> - -#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); -} - -static u8 media_not_present[] = { - 0x70, 0, 0x02, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0x3A, 0, 0, 0, 0, 0 }; -static u8 invalid_cmd_field[] = { - 0x70, 0, 0x05, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0x24, 0, 0, 0, 0, 0 }; - -void rts51x_invoke_transport(struct scsi_cmnd *srb, struct rts51x_chip *chip) -{ - int result; - -#ifdef CONFIG_PM - 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 024f115540a..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/kernel.h> - -#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 da5a9b8fb69..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> - -#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 7dd943f54c7..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 cede6c07394..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/slab.h> - -#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 79dfd27db41..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 ac58b452ecb..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/string.h> - -#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 be432351be8..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/vmalloc.h> - -#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 695a0b4d7e5..00000000000 --- 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 <http://www.gnu.org/licenses/>. - * - * 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 */ |