/* 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
