11dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong/* Driver for Realtek RTS51xx USB card reader 21dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * 31dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. 41dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * 51dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * This program is free software; you can redistribute it and/or modify it 61dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * under the terms of the GNU General Public License as published by the 71dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * Free Software Foundation; either version 2, or (at your option) any 81dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * later version. 91dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * 101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * This program is distributed in the hope that it will be useful, but 111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * WITHOUT ANY WARRANTY; without even the implied warranty of 121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * General Public License for more details. 141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * 151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * You should have received a copy of the GNU General Public License along 161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * with this program; if not, see <http://www.gnu.org/licenses/>. 171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * 181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * Author: 191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * wwang (wei_wang@realsil.com.cn) 201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China 211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * Maintainer: 221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * Edwin Rong (edwin_rong@realsil.com.cn) 231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China 241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong */ 251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include <linux/blkdev.h> 271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include <linux/kthread.h> 281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include <linux/sched.h> 291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include <linux/slab.h> 301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "debug.h" 321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "trace.h" 331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "rts51x.h" 341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "rts51x_transport.h" 351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "rts51x_scsi.h" 361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "rts51x_card.h" 371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "rts51x_chip.h" 381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#include "sd.h" 391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_CPRM 411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongstatic inline int get_rsp_type(u8 rsp_code, u8 *rsp_type, int *rsp_len) 431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!rsp_type || !rsp_len) 451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return STATUS_FAIL; 461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong switch (rsp_code) { 481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 0x03: 491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_type = SD_RSP_TYPE_R0; /* no response */ 501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_len = 0; 511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 0x04: 541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_type = SD_RSP_TYPE_R1; /* R1,R6(,R4,R5) */ 551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_len = 6; 561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 0x05: 591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_type = SD_RSP_TYPE_R1b; /* R1b */ 601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_len = 6; 611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 0x06: 641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_type = SD_RSP_TYPE_R2; /* R2 */ 651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_len = 17; 661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 0x07: 691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_type = SD_RSP_TYPE_R3; /* R3 */ 701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong *rsp_len = 6; 711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong default: 741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return STATUS_FAIL; 751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return STATUS_SUCCESS; 781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint soft_reset_sd_card(struct rts51x_chip *chip) 811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return reset_sd(chip); 831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, 861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, 871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int special_check) 881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval; 901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int timeout = 50; 911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u16 reg_addr; 921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 buf[17], stat; 931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int len = 2; 941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int rty_cnt = 0; 951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx); 971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type == SD_RSP_TYPE_R1b) 991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong timeout = 3000; 1001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongRTY_SEND_CMD: 1021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 1041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); 1061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8) (arg >> 24)); 1071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8) (arg >> 16)); 1081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8) (arg >> 8)); 1091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); 1101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); 1121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 1131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x01, PINGPONG_BUFFER); 1141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 1151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); 1161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, 1171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_TRANSFER_END); 1181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, READ_REG_CMD, SD_STAT1, 0, 0); 1201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHECK_USB(chip, USB_20)) { 1221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type == SD_RSP_TYPE_R2) { 1231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (reg_addr = PPBUF_BASE2; 1241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong reg_addr < PPBUF_BASE2 + 16; reg_addr++) { 1251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 1261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0); 1271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong len = 19; 1291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (rsp_type != SD_RSP_TYPE_R0) { 1301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* Read data from SD_CMDx registers */ 1311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; 1321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong reg_addr++) { 1331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 1341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0); 1351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong len = 8; 1371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 1381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong len = 3; 1391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, READ_REG_CMD, SD_CMD5, 0, 0); 1411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 1421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong len = 2; 1431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_CR, 100); 1461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 1471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, retval); 1481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_get_rsp(chip, len, timeout); 1501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHECK_SD_TRANS_FAIL(chip, retval)) { 1521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_clear_sd_error(chip); 1531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval == STATUS_TIMEDOUT) { 1551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type & SD_WAIT_BUSY_END) { 1561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_check_data0_status(chip); 1571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 1581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, retval); 1591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 1621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type == SD_RSP_TYPE_R0) 1651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return STATUS_SUCCESS; 1661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHECK_USB(chip, USB_20)) { 1681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_read_rsp_buf(chip, 2, buf, len - 2); 1691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 1701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type == SD_RSP_TYPE_R2) { 1711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong reg_addr = PPBUF_BASE2; 1721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong len = 16; 1731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 1741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong reg_addr = SD_CMD0; 1751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong len = 5; 1761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 1781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_seq_read_register(chip, reg_addr, 1791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (unsigned short)len, buf); 1801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 1811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, retval); 1821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_READ_REG(chip, SD_CMD5, buf + len); 1831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 1841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong stat = chip->rsp_buf[1]; 1851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((buf[0] & 0xC0) != 0) 1871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 1881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 1891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!(rsp_type & SD_NO_CHECK_CRC7)) { 1901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (stat & SD_CRC7_ERR) { 1911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd_idx == WRITE_MULTIPLE_BLOCK) 1921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 1931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rty_cnt < SD_MAX_RETRY_COUNT) { 1941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong wait_timeout(20); 1951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rty_cnt++; 1961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong goto RTY_SEND_CMD; 1971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 1981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 1991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) || 2041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) { 2051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) { 2061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (buf[1] & 0x80) 2071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 2081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 2101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (buf[1] & 0x7D) { 2111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#else 2121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (buf[1] & 0x7F) { 2131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 2141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 2151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (buf[2] & 0xF8) 2171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 2181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd_idx == SELECT_CARD) { 2201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type == SD_RSP_TYPE_R2) { 2211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((buf[3] & 0x1E) != 0x04) 2221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 2231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (rsp_type == SD_RSP_TYPE_R2) { 2241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((buf[3] & 0x1E) != 0x03) 2251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 2261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp && rsp_len) 2311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong memcpy(rsp, buf, rsp_len); 2321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return STATUS_SUCCESS; 2341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 2351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 236aa2f92ae6b986934ff220eda6b5c91f4ee294b35Márton Némethint ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type) 2371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 2381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval, rsp_len; 2391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u16 reg_addr; 2401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type == SD_RSP_TYPE_R0) 2421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return STATUS_SUCCESS; 2431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 2451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp_type == SD_RSP_TYPE_R2) { 2471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; 2481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong reg_addr++) { 2491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); 2501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rsp_len = 17; 2521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (rsp_type != SD_RSP_TYPE_R0) { 2531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; reg_addr++) 2541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); 2551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rsp_len = 6; 2561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, READ_REG_CMD, SD_CMD5, 0xFF, 0); 2581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_CR, 100); 2601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 2611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, retval); 2621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_get_rsp(chip, rsp_len, 100); 2641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 2661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, retval); 2671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (rsp) { 2691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int min_len = (rsp_len < len) ? rsp_len : len; 2701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong memcpy(rsp, rts51x_get_rsp_data(chip), min_len); 2721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("min_len = %d\n", min_len); 2741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n", 2751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rsp[0], rsp[1], rsp[2], rsp[3]); 2761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return STATUS_SUCCESS; 2791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 2801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, 2821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code, 2831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u32 arg) 2841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 2851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 2861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval, rsp_len; 2871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 rsp_type; 2881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_switch_clock(chip); 2901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 2911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 2921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 2931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_card->pre_cmd_err) { 2941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 0; 2951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 2961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 2971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 2981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); 2991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 3001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 3011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 3021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->last_rsp_type = rsp_type; 3041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_switch_clock(chip); 3061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 3081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 3091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { 3101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHK_MMC_8BIT(sd_card)) { 3111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 3121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_CFG1, 0x03, 3131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_BUS_WIDTH_8); 3141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 3161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { 3171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 3181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_CFG1, 0x03, 3191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_BUS_WIDTH_4); 3201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 3221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#else 3251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* Set H/W SD/MMC Bus Width */ 3261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); 3271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 3281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (standby) { 3301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_select_card(chip, 0); 3311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Cmd_Failed); 3331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (acmd) { 3361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 3371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, 3381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 0); 3391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Cmd_Failed); 3411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, 3441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->rsp, rsp_len, 0); 3451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Cmd_Failed); 3471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (standby) { 3491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_select_card(chip, 1); 3501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Cmd_Failed); 3521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 3541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* Get SD lock status */ 3551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_update_lock_status(chip); 3561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Cmd_Failed); 3581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 3591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return TRANSPORT_GOOD; 3611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongSD_Execute_Cmd_Failed: 3631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 1; 3641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); 3651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong release_sd_card(chip); 3661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong do_reset_sd_card(chip); 3671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!(chip->card_ready & SD_CARD)) 3681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 3691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 3711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 3721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, 3741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 cmd_idx, u8 cmd12, u8 standby, 3751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 acmd, u8 rsp_code, u32 arg, u32 data_len, 3761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong void *data_buf, unsigned int buf_len, int use_sg) 3771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 3781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 3791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval, rsp_len, i; 3801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int cmd13_checkbit = 0, read_err = 0; 3811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 rsp_type, bus_width; 3821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_card->pre_cmd_err) { 3841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 0; 3851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 3861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 3871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_switch_clock(chip); 3901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 3911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 3921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); 3931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 3941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 3951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 3961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 3971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->last_rsp_type = rsp_type; 3981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 3991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_switch_clock(chip); 4001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 4011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 4021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 4031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { 4041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHK_MMC_8BIT(sd_card)) 4051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong bus_width = SD_BUS_WIDTH_8; 4061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) 4071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong bus_width = SD_BUS_WIDTH_4; 4081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong else 4091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong bus_width = SD_BUS_WIDTH_1; 4101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 4111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong bus_width = SD_BUS_WIDTH_4; 4121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 4131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("bus_width = %d\n", bus_width); 4141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#else 4151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong bus_width = SD_BUS_WIDTH_4; 4161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 4171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (data_len < 512) { 4191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, 4201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 0); 4211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 4221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 4231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 4241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (standby) { 4261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_select_card(chip, 0); 4271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 4281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 4291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 4301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (acmd) { 4321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 4331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, 4341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 0); 4351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 4361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 4371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 4381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (data_len <= 512) { 4401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int min_len; 4411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 *buf; 4421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u16 byte_cnt, blk_cnt; 4431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 cmd[5]; 4441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int offset = 0; 4451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong void *sg = NULL; 4461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong byte_cnt = (u16) (data_len & 0x3FF); 4481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong blk_cnt = 1; 4491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd[0] = 0x40 | cmd_idx; 4511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd[1] = (u8) (arg >> 24); 4521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd[2] = (u8) (arg >> 16); 4531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd[3] = (u8) (arg >> 8); 4541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd[4] = (u8) arg; 4551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf = kmalloc(data_len, GFP_KERNEL); 4571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (buf == NULL) 4581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_ERROR); 4591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, 4611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong blk_cnt, bus_width, buf, data_len, 2000); 4621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 4631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong read_err = 1; 4641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong kfree(buf); 4651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, CARD_STOP, 4661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR, 4671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR); 4681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 4691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 4701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong min_len = min(data_len, buf_len); 4721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (use_sg) 4731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_access_sglist(buf, min_len, (void *)data_buf, 4741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong &sg, &offset, TO_XFER_BUF); 4751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong else 4761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong memcpy(data_buf, buf, min_len); 4771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 4781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong kfree(buf); 4791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (!(data_len & 0x1FF)) { 4801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 4811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); 4821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); 4831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 4841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0xFF, (u8) (data_len >> 17)); 4851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 4861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0xFF, (u8) ((data_len & 0x0001FE00) >> 9)); 4871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 4881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x40 | cmd_idx); 4891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, 4901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u8) (arg >> 24)); 4911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, 4921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u8) (arg >> 16)); 4931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, 4941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u8) (arg >> 8)); 4951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); 4961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); 4971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); 4981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); 4991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, 5001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_TM_AUTO_READ_2 | SD_TRANSFER_START); 5011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, 5021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_TRANSFER_END, SD_TRANSFER_END); 5031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_CDIR, 100); 5041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 5051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong read_err = 1; 5061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_ep0_write_register(chip, CARD_STOP, 5071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR, 5081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR); 5091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 5131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_transfer_data_rcc(chip, RCV_BULK_PIPE(chip), 5141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong data_buf, buf_len, use_sg, NULL, 5151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10000, STAGE_DI); 5161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 5171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong read_err = 1; 5181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_ep0_write_register(chip, CARD_STOP, 5191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR, 5201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR); 5211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_get_rsp(chip, 1, 500); 5241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHECK_SD_TRANS_FAIL(chip, retval)) { 5251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong read_err = 1; 5261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_ep0_write_register(chip, CARD_STOP, 5271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR, 5281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR); 5291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 5321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); 5361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 5371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (standby) { 5401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_select_card(chip, 1); 5411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 5421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd12) { 5461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 5471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0, SD_RSP_TYPE_R1b, NULL, 0, 5481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0); 5491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 5501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (data_len < 512) { 5541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, 5551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 0); 5561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 5571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); 5601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); 5611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (standby || cmd12) 5641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd13_checkbit = 1; 5651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (i = 0; i < 3; i++) { 5671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 5681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, 5691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 5701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd13_checkbit); 5711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval == STATUS_SUCCESS) 5721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 5731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 5741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 5751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); 5761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return TRANSPORT_GOOD; 5781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongSD_Execute_Read_Cmd_Failed: 5801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 1; 5811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); 5821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (read_err) 5831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 5841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong release_sd_card(chip); 5851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong do_reset_sd_card(chip); 5861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!(chip->card_ready & SD_CARD)) 5871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 5881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 5901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 5911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 5921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, 5931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, 5941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 rsp_code, u32 arg, u32 data_len, 5951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong void *data_buf, unsigned int buf_len, int use_sg) 5961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 5971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 5981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval, rsp_len; 5991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int cmd13_checkbit = 0, write_err = 0; 6001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 rsp_type; 6011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u32 i; 6021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 6031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int lock_cmd_fail = 0; 6041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 sd_lock_state = 0; 6051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 lock_cmd_type = 0; 6061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 6071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_card->pre_cmd_err) { 6091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 0; 6101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 6111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 6121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_switch_clock(chip); 6151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, STATUS_FAIL); 6171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 6181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd_idx == LOCK_UNLOCK) { 6191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_lock_state = sd_card->sd_lock_status; 6201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_lock_state &= SD_LOCKED; 6211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 6231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); 6251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 6261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 6271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 6281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->last_rsp_type = rsp_type; 6301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_switch_clock(chip); 6321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 6341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 6351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { 6361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHK_MMC_8BIT(sd_card)) { 6371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 6381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_CFG1, 0x03, 6391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_BUS_WIDTH_8); 6401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 6421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { 6431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 6441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_CFG1, 0x03, 6451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_BUS_WIDTH_4); 6461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 6481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#else 6511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); 6521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 6531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (data_len < 512) { 6551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, 6561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 0); 6571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 6591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (standby) { 6621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_select_card(chip, 0); 6631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 6651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (acmd) { 6681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 6691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, 6701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 0); 6711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 6731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 6741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, 6761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->rsp, rsp_len, 0); 6771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 6781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 6791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (data_len <= 512) { 6811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 *buf; 6821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int offset = 0; 6831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong void *sg = NULL; 6841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf = kmalloc(data_len, GFP_KERNEL); 6861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (buf == NULL) 6871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_ERROR); 6881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (use_sg) 6901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_access_sglist(buf, data_len, (void *)data_buf, 6911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong &sg, &offset, FROM_XFER_BUF); 6921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong else 6931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong memcpy(buf, data_buf, data_len); 6941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 6951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 6961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd_idx == LOCK_UNLOCK) 6971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong lock_cmd_type = buf[0] & 0x0F; 6981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 6991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (data_len > 256) { 7011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 7021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (i = 0; i < 256; i++) { 7031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, 7041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u16) (PPBUF_BASE2 + i), 0xFF, 7051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[i]); 7061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_C, 250); 7081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 7091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong kfree(buf); 7101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 7141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (i = 256; i < data_len; i++) { 7151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, 7161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u16) (PPBUF_BASE2 + i), 0xFF, 7171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[i]); 7181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_C, 250); 7201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 7211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong kfree(buf); 7221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 7251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 7261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (i = 0; i < data_len; i++) { 7271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, 7281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u16) (PPBUF_BASE2 + i), 0xFF, 7291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[i]); 7301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_C, 250); 7321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 7331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong kfree(buf); 7341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong kfree(buf); 7391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 7411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 7431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u8) ((data_len >> 8) & 0x03)); 7441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 7451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (u8) data_len); 7461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x00); 7471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x01); 7481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, 7491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong PINGPONG_BUFFER); 7501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, 7521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); 7531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, 7541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_TRANSFER_END, SD_TRANSFER_END); 7551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_CR, 100); 7571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 7581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_get_rsp(chip, 1, 250); 7611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHECK_SD_TRANS_FAIL(chip, retval)) 7621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (!(data_len & 0x1FF)) { 7641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 7651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); 7671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); 7681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 7691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0xFF, (u8) (data_len >> 17)); 7701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 7711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0xFF, (u8) ((data_len & 0x0001FE00) >> 9)); 7721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); 7741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, 7761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); 7771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, 7781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_TRANSFER_END, SD_TRANSFER_END); 7791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_CDOR, 100); 7811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 7821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 7851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), 7861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong data_buf, buf_len, use_sg, NULL, 7871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10000, STAGE_DO); 7881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 7891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_get_rsp(chip, 1, 10000); 7921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHECK_SD_TRANS_FAIL(chip, retval)) 7931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 7961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 7971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 7981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 7991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval < 0) { 8001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong write_err = 1; 8011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, 8021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_STOP | SD_CLR_ERR); 8031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 8041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 8061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd_idx == LOCK_UNLOCK) { 8071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (lock_cmd_type == SD_ERASE) { 8081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_erase_status = SD_UNDER_ERASING; 8091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_set_resid(srb, 0); 8101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return TRANSPORT_GOOD; 8111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_init_cmd(chip); 8141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, 8151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_DAT0_STATUS); 8161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = rts51x_send_cmd(chip, MODE_CR, 250); 8171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 8181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 8191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_get_rsp(chip, 1, 200); /* Don't care return value */ 8201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_update_lock_status(chip); 8221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 8231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("Lock command fail!\n"); 8241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong lock_cmd_fail = 1; 8251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif /* SUPPORT_SD_LOCK */ 8281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (standby) { 8301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = sd_select_card(chip, 1); 8311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 8321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 8331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd12) { 8361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 8371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0, SD_RSP_TYPE_R1b, NULL, 0, 8381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0); 8391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 8401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 8411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (data_len < 512) { 8441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, 8451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 0); 8461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 8471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 8481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); 8501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); 8511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd12 || standby) { 8541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* There is CMD7 or CMD12 sent before CMD13 */ 8551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd13_checkbit = 1; 8561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong for (i = 0; i < 3; i++) { 8591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 8601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, 8611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_RSP_TYPE_R1, NULL, 0, 8621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd13_checkbit); 8631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval == STATUS_SUCCESS) 8641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 8651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) 8671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); 8681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 8691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (cmd_idx == LOCK_UNLOCK) { 8701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!lock_cmd_fail) { 8711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("lock_cmd_type = 0x%x\n", 8721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong lock_cmd_type); 8731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (lock_cmd_type & SD_CLR_PWD) 8741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status &= ~SD_PWD_EXIST; 8751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (lock_cmd_type & SD_SET_PWD) 8761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status |= SD_PWD_EXIST; 8771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 8791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("sd_lock_state = 0x%x," 8801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong "sd_card->sd_lock_status = 0x%x\n", 8811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_lock_state, sd_card->sd_lock_status); 8821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { 8831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_notify = 1; 8841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_lock_state) { 8851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_card->sd_lock_status & 8861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_LOCK_1BIT_MODE) { 8871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status |= 8881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong (SD_UNLOCK_POW_ON | SD_SDR_RST); 8891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (CHK_SD(sd_card)) { 8901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = reset_sd(chip); 8911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 8921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status 8931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong &= ~(SD_UNLOCK_POW_ON | 8941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_SDR_RST); 8951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_GOTO(chip, 8961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SD_Execute_Write_Cmd_Failed); 8971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 8991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status &= 9011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ~(SD_UNLOCK_POW_ON | SD_SDR_RST); 9021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (lock_cmd_fail) { 9081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_set_resid(srb, 0); 9091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); 9101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 9111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif /* SUPPORT_SD_LOCK */ 9131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return TRANSPORT_GOOD; 9151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongSD_Execute_Write_Cmd_Failed: 9171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 1; 9181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); 9191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (write_err) 9201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); 9211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong release_sd_card(chip); 9221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong do_reset_sd_card(chip); 9231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!(chip->card_ready & SD_CARD)) 9241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 9251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 9271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 9281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) 9301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 9311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 9321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int lun = SCSI_LUN(srb); 9331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int len; 9341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 buf[18] = { 9351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, 9361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, 9371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, 9381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x0E, 9391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, /* Version Number */ 9401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, /* WP | Media Type */ 9411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, /* RCA (Low byte) */ 9421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, /* RCA (High byte) */ 9431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x53, /* 'S' */ 9441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x44, /* 'D' */ 9451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x20, /* ' ' */ 9461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x43, /* 'C' */ 9471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x61, /* 'a' */ 9481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x72, /* 'r' */ 9491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x64, /* 'd' */ 9501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, /* Max LUN Number */ 9511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, 9521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 0x00, 9531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong }; 9541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 0; 9561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!(CHK_BIT(chip->lun_mc, lun))) { 9581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong SET_BIT(chip->lun_mc, lun); 9591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 9601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 9611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) 9641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) 9651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) 9661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong || (0x64 != srb->cmnd[8])) { 9671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 9681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 9691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong switch (srb->cmnd[1] & 0x0F) { 9721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 0: 9731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_pass_thru_en = 0; 9741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 9751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 1: 9771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_pass_thru_en = 1; 9781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 9791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong default: 9811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 9821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 9831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 9841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* 0x01:SD Memory Card; 0x02:Other Media; 0x03:Illegal Media; */ 9861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[5] = (1 == CHK_SD(sd_card)) ? 0x01 : 0x02; 9871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (chip->card_wp & SD_CARD) 9881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[5] |= 0x80; 9891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[6] = (u8) (sd_card->sd_addr >> 16); 9911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[7] = (u8) (sd_card->sd_addr >> 24); 9921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong buf[15] = chip->max_lun; 9941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong len = min(18, (int)scsi_bufflen(srb)); 9961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_set_xfer_buf(buf, len, srb); 9971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 9981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return TRANSPORT_GOOD; 9991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 10001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) 10021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 10031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 10041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int lun = SCSI_LUN(srb); 10051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval; 10061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 cmd_idx, rsp_code; 10071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 standby = 0, acmd = 0; 10081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u32 arg; 10091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!sd_card->sd_pass_thru_en) { 10111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 10121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 10131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 10141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd_idx = srb->cmnd[2] & 0x3F; 10161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x02) 10171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong standby = 1; 10181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x01) 10191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong acmd = 1; 10201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong arg = ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | 10221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; 10231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rsp_code = srb->cmnd[10]; 10251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 10271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_execute_no_data(chip, lun, cmd_idx, standby, acmd, rsp_code, 10281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong arg); 10291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_set_resid(srb, 0); 10301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return retval; 10311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 10321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) 10341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 10351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 10361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval; 10371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int lun = SCSI_LUN(srb); 10381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 cmd_idx, rsp_code, send_cmd12 = 0, standby = 0, acmd = 0; 10391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u32 arg, data_len; 10401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!sd_card->sd_pass_thru_en) { 10421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 10431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 10441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 10451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd_idx = srb->cmnd[2] & 0x3F; 10471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x04) 10481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong send_cmd12 = 1; 10491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x02) 10501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong standby = 1; 10511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x01) 10521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong acmd = 1; 10531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong arg = ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | 10551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; 10561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong data_len = 10581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ((u32) srb->cmnd[7] << 16) | ((u32) srb->cmnd[8] << 8) | 10591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong srb->cmnd[9]; 10601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rsp_code = srb->cmnd[10]; 10611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 10631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_execute_read_data(chip, lun, cmd_idx, send_cmd12, standby, 10641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong acmd, rsp_code, arg, data_len, 10651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_sglist(srb), scsi_bufflen(srb), 10661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_sg_count(srb)); 10671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_set_resid(srb, 0); 10681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return retval; 10691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 10701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) 10721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 10731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 10741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval; 10751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int lun = SCSI_LUN(srb); 10761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u8 cmd_idx, rsp_code, send_cmd12 = 0, standby = 0, acmd = 0; 10771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u32 data_len, arg; 10781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!sd_card->sd_pass_thru_en) { 10801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 10811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 10821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 10831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong cmd_idx = srb->cmnd[2] & 0x3F; 10851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x04) 10861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong send_cmd12 = 1; 10871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x02) 10881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong standby = 1; 10891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (srb->cmnd[1] & 0x01) 10901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong acmd = 1; 10911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 10921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong data_len = 10931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ((u32) srb->cmnd[7] << 16) | ((u32) srb->cmnd[8] << 8) | 10941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong srb->cmnd[9]; 10951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong arg = 10961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | 10971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; 10981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rsp_code = srb->cmnd[10]; 10991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = 11011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong ext_sd_execute_write_data(chip, lun, cmd_idx, send_cmd12, standby, 11021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong acmd, rsp_code, arg, data_len, 11031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_sglist(srb), scsi_bufflen(srb), 11041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_sg_count(srb)); 11051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_set_resid(srb, 0); 11061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return retval; 11071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 11081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) 11101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 11111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 11121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int lun = SCSI_LUN(srb); 11131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int count; 11141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong u16 data_len; 11151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11161dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!sd_card->sd_pass_thru_en) { 11171dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 11181dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 11191dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11201dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11211dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_card->pre_cmd_err) { 11221dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 0; 11231dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 11241dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 11251dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11261dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11271dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong data_len = ((u16) srb->cmnd[7] << 8) | srb->cmnd[8]; 11281dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11291dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { 11301dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 11311dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 11321dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { 11331dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong count = (data_len < 17) ? data_len : 17; 11341dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } else { 11351dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong count = (data_len < 6) ? data_len : 6; 11361dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11371dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong rts51x_set_xfer_buf(sd_card->rsp, count, srb); 11381dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11391dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("Response length: %d\n", data_len); 11401dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong RTS51X_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", 11411dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->rsp[0], sd_card->rsp[1], sd_card->rsp[2], 11421dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->rsp[3]); 11431dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11441dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_set_resid(srb, 0); 11451dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return TRANSPORT_GOOD; 11461dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 11471dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11481dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rongint sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) 11491dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong{ 11501dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong struct sd_info *sd_card = &(chip->sd_card); 11511dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong unsigned int lun = SCSI_LUN(srb); 11521dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong int retval; 11531dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11541dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (!sd_card->sd_pass_thru_en) { 11551dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 11561dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 11571dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11581dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11591dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (sd_card->pre_cmd_err) { 11601dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 0; 11611dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 11621dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 11631dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11641dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11651dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) 11661dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) 11671dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) 11681dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong || (0x64 != srb->cmnd[8])) { 11691dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 11701dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 11711dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11721dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11731dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong switch (srb->cmnd[1] & 0x0F) { 11741dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 0: 11751dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* SD Card Power Off -> ON and Initialization */ 11761dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 11771dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (0x64 == srb->cmnd[9]) { 11781dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* Command Mode */ 11791dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status |= SD_SDR_RST; 11801dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11811dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif /* SUPPORT_SD_LOCK */ 11821dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = reset_sd_card(chip); 11831dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 11841dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 11851dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status &= ~SD_SDR_RST; 11861dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 11871dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 11881dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 1; 11891dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 11901dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 11911dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#ifdef SUPPORT_SD_LOCK 11921dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->sd_lock_status &= ~SD_SDR_RST; 11931dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 11941dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 11951dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 11961dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong case 1: 11971dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong /* reset CMD(CMD0) and Initialization 11981dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong * (without SD Card Power Off -> ON) */ 11991dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong retval = soft_reset_sd_card(chip); 12001dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong if (retval != STATUS_SUCCESS) { 12011dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 12021dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong sd_card->pre_cmd_err = 1; 12031dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 12041dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 12051dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong break; 12061dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 12071dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong default: 12081dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 12091dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong TRACE_RET(chip, TRANSPORT_FAILED); 12101dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong } 12111dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong 12121dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong scsi_set_resid(srb, 0); 12131dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong return TRANSPORT_GOOD; 12141dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong} 12151dac4186bcc663cb8c2bcc59481aea8fe9124a6cedwin_rong#endif 1216