brintos

brintos / linux-shallow public Read only

0
0
Text · 53.5 KiB · c0af378 Raw
2146 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Driver for Realtek PCI-Express card reader4 *5 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.6 *7 * Author:8 *   Wei WANG (wei_wang@realsil.com.cn)9 *   Micky Ching (micky_ching@realsil.com.cn)10 */11 12#include <linux/blkdev.h>13#include <linux/kthread.h>14#include <linux/sched.h>15#include <linux/vmalloc.h>16 17#include "rtsx.h"18#include "rtsx_transport.h"19#include "rtsx_scsi.h"20#include "rtsx_card.h"21#include "xd.h"22 23static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no);24static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff,25			u8 start_page, u8 end_page);26 27static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code)28{29	struct xd_info *xd_card = &chip->xd_card;30 31	xd_card->err_code = err_code;32}33 34static int xd_set_init_para(struct rtsx_chip *chip)35{36	struct xd_info *xd_card = &chip->xd_card;37	int retval;38 39	if (chip->asic_code)40		xd_card->xd_clock = 47;41	else42		xd_card->xd_clock = CLK_50;43 44	retval = switch_clock(chip, xd_card->xd_clock);45	if (retval != STATUS_SUCCESS)46		return STATUS_FAIL;47 48	return STATUS_SUCCESS;49}50 51static int xd_switch_clock(struct rtsx_chip *chip)52{53	struct xd_info *xd_card = &chip->xd_card;54	int retval;55 56	retval = select_card(chip, XD_CARD);57	if (retval != STATUS_SUCCESS)58		return STATUS_FAIL;59 60	retval = switch_clock(chip, xd_card->xd_clock);61	if (retval != STATUS_SUCCESS)62		return STATUS_FAIL;63 64	return STATUS_SUCCESS;65}66 67static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len)68{69	int retval, i;70	u8 *ptr;71 72	rtsx_init_cmd(chip);73 74	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd);75	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,76		     XD_TRANSFER_START | XD_READ_ID);77	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END,78		     XD_TRANSFER_END);79 80	for (i = 0; i < 4; i++)81		rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0);82 83	retval = rtsx_send_cmd(chip, XD_CARD, 20);84	if (retval < 0)85		return STATUS_FAIL;86 87	ptr = rtsx_get_cmd_data(chip) + 1;88	if (id_buf && buf_len) {89		if (buf_len > 4)90			buf_len = 4;91		memcpy(id_buf, ptr, buf_len);92	}93 94	return STATUS_SUCCESS;95}96 97static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode)98{99	struct xd_info *xd_card = &chip->xd_card;100 101	switch (mode) {102	case XD_RW_ADDR:103		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0);104		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr);105		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2,106			     0xFF, (u8)(addr >> 8));107		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3,108			     0xFF, (u8)(addr >> 16));109		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF,110			     xd_card->addr_cycle |111			     XD_CALC_ECC |112			     XD_BA_NO_TRANSFORM);113		break;114 115	case XD_ERASE_ADDR:116		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr);117		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1,118			     0xFF, (u8)(addr >> 8));119		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2,120			     0xFF, (u8)(addr >> 16));121		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF,122			     (xd_card->addr_cycle - 1) | XD_CALC_ECC |123			XD_BA_NO_TRANSFORM);124		break;125 126	default:127		break;128	}129}130 131static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr,132			     u8 *buf, int buf_len)133{134	int retval, i;135 136	rtsx_init_cmd(chip);137 138	xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);139 140	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,141		     0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT);142	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,143		     XD_TRANSFER_END, XD_TRANSFER_END);144 145	for (i = 0; i < 6; i++)146		rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i),147			     0, 0);148	for (i = 0; i < 4; i++)149		rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i),150			     0, 0);151	rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0);152 153	retval = rtsx_send_cmd(chip, XD_CARD, 500);154	if (retval < 0)155		return STATUS_FAIL;156 157	if (buf && buf_len) {158		u8 *ptr = rtsx_get_cmd_data(chip) + 1;159 160		if (buf_len > 11)161			buf_len = 11;162		memcpy(buf, ptr, buf_len);163	}164 165	return STATUS_SUCCESS;166}167 168static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset,169				 u8 *buf, int buf_len)170{171	int retval, i;172 173	if (!buf || buf_len < 0)174		return STATUS_FAIL;175 176	rtsx_init_cmd(chip);177 178	for (i = 0; i < buf_len; i++)179		rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i,180			     0, 0);181 182	retval = rtsx_send_cmd(chip, 0, 250);183	if (retval < 0) {184		rtsx_clear_xd_error(chip);185		return STATUS_FAIL;186	}187 188	memcpy(buf, rtsx_get_cmd_data(chip), buf_len);189 190	return STATUS_SUCCESS;191}192 193static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf,194		       int buf_len)195{196	int retval;197	u8 reg;198 199	if (!buf || buf_len < 10)200		return STATUS_FAIL;201 202	rtsx_init_cmd(chip);203 204	xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);205 206	rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,207		     0x01, PINGPONG_BUFFER);208	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);209	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,210		     XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);211 212	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,213		     XD_TRANSFER_START | XD_READ_PAGES);214	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END,215		     XD_TRANSFER_END);216 217	retval = rtsx_send_cmd(chip, XD_CARD, 250);218	if (retval == -ETIMEDOUT) {219		rtsx_clear_xd_error(chip);220		return STATUS_FAIL;221	}222 223	retval = rtsx_read_register(chip, XD_PAGE_STATUS, &reg);224	if (retval)225		return retval;226	if (reg != XD_GPG) {227		rtsx_clear_xd_error(chip);228		return STATUS_FAIL;229	}230 231	retval = rtsx_read_register(chip, XD_CTL, &reg);232	if (retval)233		return retval;234	if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) {235		retval = xd_read_data_from_ppb(chip, 0, buf, buf_len);236		if (retval != STATUS_SUCCESS)237			return STATUS_FAIL;238		if (reg & XD_ECC1_ERROR) {239			u8 ecc_bit, ecc_byte;240 241			retval = rtsx_read_register(chip, XD_ECC_BIT1,242						    &ecc_bit);243			if (retval)244				return retval;245			retval = rtsx_read_register(chip, XD_ECC_BYTE1,246						    &ecc_byte);247			if (retval)248				return retval;249 250			dev_dbg(rtsx_dev(chip), "ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n",251				ecc_bit, ecc_byte);252			if (ecc_byte < buf_len) {253				dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n",254					buf[ecc_byte]);255				buf[ecc_byte] ^= (1 << ecc_bit);256				dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n",257					buf[ecc_byte]);258			}259		}260	} else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) {261		rtsx_clear_xd_error(chip);262 263		retval = xd_read_data_from_ppb(chip, 256, buf, buf_len);264		if (retval != STATUS_SUCCESS)265			return STATUS_FAIL;266		if (reg & XD_ECC2_ERROR) {267			u8 ecc_bit, ecc_byte;268 269			retval = rtsx_read_register(chip, XD_ECC_BIT2,270						    &ecc_bit);271			if (retval)272				return retval;273			retval = rtsx_read_register(chip, XD_ECC_BYTE2,274						    &ecc_byte);275			if (retval)276				return retval;277 278			dev_dbg(rtsx_dev(chip), "ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n",279				ecc_bit, ecc_byte);280			if (ecc_byte < buf_len) {281				dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n",282					buf[ecc_byte]);283				buf[ecc_byte] ^= (1 << ecc_bit);284				dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n",285					buf[ecc_byte]);286			}287		}288	} else {289		rtsx_clear_xd_error(chip);290		return STATUS_FAIL;291	}292 293	return STATUS_SUCCESS;294}295 296static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip)297{298	if (CHECK_PID(chip, 0x5208)) {299		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,300			     XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);301		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,302			     XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);303		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,304			     XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU);305		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,306			     XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD);307		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,308			     MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);309		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF,310			     MS_D5_PD | MS_D4_PD);311	} else if (CHECK_PID(chip, 0x5288)) {312		if (CHECK_BARO_PKG(chip, QFN)) {313			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1,314				     0xFF, 0x55);315			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2,316				     0xFF, 0x55);317			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3,318				     0xFF, 0x4B);319			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4,320				     0xFF, 0x69);321		}322	}323}324 325static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip)326{327	if (CHECK_BARO_PKG(chip, QFN)) {328		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);329		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);330		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B);331		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);332	}333}334 335static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip)336{337	if (CHECK_PID(chip, 0x5208)) {338		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF,339			     XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD);340		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF,341			     XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD);342		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF,343			     XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU);344		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF,345			     XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD);346		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF,347			     MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD);348		rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF,349			     MS_D5_PD | MS_D4_PD);350	} else if (CHECK_PID(chip, 0x5288)) {351		if (CHECK_BARO_PKG(chip, QFN)) {352			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1,353				     0xFF, 0x55);354			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2,355				     0xFF, 0x55);356			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3,357				     0xFF, 0x53);358			rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4,359				     0xFF, 0xA9);360		}361	}362}363 364static int xd_pull_ctl_disable(struct rtsx_chip *chip)365{366	int retval;367 368	if (CHECK_PID(chip, 0x5208)) {369		retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF,370					     XD_D3_PD |371					     XD_D2_PD |372					     XD_D1_PD |373					     XD_D0_PD);374		if (retval)375			return retval;376		retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF,377					     XD_D7_PD |378					     XD_D6_PD |379					     XD_D5_PD |380					     XD_D4_PD);381		if (retval)382			return retval;383		retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF,384					     XD_WP_PD |385					     XD_CE_PD |386					     XD_CLE_PD |387					     XD_CD_PU);388		if (retval)389			return retval;390		retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF,391					     XD_RDY_PD |392					     XD_WE_PD |393					     XD_RE_PD |394					     XD_ALE_PD);395		if (retval)396			return retval;397		retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF,398					     MS_INS_PU |399					     SD_WP_PD |400					     SD_CD_PU |401					     SD_CMD_PD);402		if (retval)403			return retval;404		retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF,405					     MS_D5_PD | MS_D4_PD);406		if (retval)407			return retval;408	} else if (CHECK_PID(chip, 0x5288)) {409		if (CHECK_BARO_PKG(chip, QFN)) {410			retval = rtsx_write_register(chip, CARD_PULL_CTL1,411						     0xFF, 0x55);412			if (retval)413				return retval;414			retval = rtsx_write_register(chip, CARD_PULL_CTL2,415						     0xFF, 0x55);416			if (retval)417				return retval;418			retval = rtsx_write_register(chip, CARD_PULL_CTL3,419						     0xFF, 0x4B);420			if (retval)421				return retval;422			retval = rtsx_write_register(chip, CARD_PULL_CTL4,423						     0xFF, 0x69);424			if (retval)425				return retval;426		}427	}428 429	return STATUS_SUCCESS;430}431 432static int reset_xd(struct rtsx_chip *chip)433{434	struct xd_info *xd_card = &chip->xd_card;435	int retval, i, j;436	u8 *ptr, id_buf[4], redunt[11];437 438	retval = select_card(chip, XD_CARD);439	if (retval != STATUS_SUCCESS)440		return STATUS_FAIL;441 442	rtsx_init_cmd(chip);443 444	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF,445		     XD_PGSTS_NOT_FF);446	if (chip->asic_code) {447		if (!CHECK_PID(chip, 0x5288))448			xd_fill_pull_ctl_disable(chip);449		else450			xd_fill_pull_ctl_stage1_barossa(chip);451	} else {452		rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,453			     (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) |454			     0x20);455	}456 457	if (!chip->ft2_fast_mode)458		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT,459			     XD_NO_AUTO_PWR_OFF, 0);460 461	rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0);462 463	retval = rtsx_send_cmd(chip, XD_CARD, 100);464	if (retval < 0)465		return STATUS_FAIL;466 467	if (!chip->ft2_fast_mode) {468		retval = card_power_off(chip, XD_CARD);469		if (retval != STATUS_SUCCESS)470			return STATUS_FAIL;471 472		wait_timeout(250);473 474		rtsx_init_cmd(chip);475 476		if (chip->asic_code) {477			xd_fill_pull_ctl_enable(chip);478		} else {479			rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,480				     (FPGA_XD_PULL_CTL_EN1 &481				      FPGA_XD_PULL_CTL_EN2) |482				     0x20);483		}484 485		retval = rtsx_send_cmd(chip, XD_CARD, 100);486		if (retval < 0)487			return STATUS_FAIL;488 489		retval = card_power_on(chip, XD_CARD);490		if (retval != STATUS_SUCCESS)491			return STATUS_FAIL;492 493#ifdef SUPPORT_OCP494		wait_timeout(50);495		if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {496			dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n",497				chip->ocp_stat);498			return STATUS_FAIL;499		}500#endif501	}502 503	rtsx_init_cmd(chip);504 505	if (chip->ft2_fast_mode) {506		if (chip->asic_code) {507			xd_fill_pull_ctl_enable(chip);508		} else {509			rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF,510				     (FPGA_XD_PULL_CTL_EN1 &511				      FPGA_XD_PULL_CTL_EN2) |512				     0x20);513		}514	}515 516	rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN);517	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN);518 519	retval = rtsx_send_cmd(chip, XD_CARD, 100);520	if (retval < 0)521		return STATUS_FAIL;522 523	if (!chip->ft2_fast_mode)524		wait_timeout(200);525 526	retval = xd_set_init_para(chip);527	if (retval != STATUS_SUCCESS)528		return STATUS_FAIL;529 530	/* Read ID to check if the timing setting is right */531	for (i = 0; i < 4; i++) {532		rtsx_init_cmd(chip);533 534		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF,535			     XD_TIME_SETUP_STEP * 3 +536			     XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i);537		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF,538			     XD_TIME_SETUP_STEP * 3 +539			     XD_TIME_RW_STEP * (4 + i) +540			     XD_TIME_RWN_STEP * (3 + i));541 542		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,543			     XD_TRANSFER_START | XD_RESET);544		rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,545			     XD_TRANSFER_END, XD_TRANSFER_END);546 547		rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);548		rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);549 550		retval = rtsx_send_cmd(chip, XD_CARD, 100);551		if (retval < 0)552			return STATUS_FAIL;553 554		ptr = rtsx_get_cmd_data(chip) + 1;555 556		dev_dbg(rtsx_dev(chip), "XD_DAT: 0x%x, XD_CTL: 0x%x\n",557			ptr[0], ptr[1]);558 559		if (((ptr[0] & READY_FLAG) != READY_STATE) ||560		    !(ptr[1] & XD_RDY))561			continue;562 563		retval = xd_read_id(chip, READ_ID, id_buf, 4);564		if (retval != STATUS_SUCCESS)565			return STATUS_FAIL;566 567		dev_dbg(rtsx_dev(chip), "READ_ID: 0x%x 0x%x 0x%x 0x%x\n",568			id_buf[0], id_buf[1], id_buf[2], id_buf[3]);569 570		xd_card->device_code = id_buf[1];571 572		/* Check if the xD card is supported */573		switch (xd_card->device_code) {574		case XD_4M_X8_512_1:575		case XD_4M_X8_512_2:576			xd_card->block_shift = 4;577			xd_card->page_off = 0x0F;578			xd_card->addr_cycle = 3;579			xd_card->zone_cnt = 1;580			xd_card->capacity = 8000;581			XD_SET_4MB(xd_card);582			break;583		case XD_8M_X8_512:584			xd_card->block_shift = 4;585			xd_card->page_off = 0x0F;586			xd_card->addr_cycle = 3;587			xd_card->zone_cnt = 1;588			xd_card->capacity = 16000;589			break;590		case XD_16M_X8_512:591			XD_PAGE_512(xd_card);592			xd_card->addr_cycle = 3;593			xd_card->zone_cnt = 1;594			xd_card->capacity = 32000;595			break;596		case XD_32M_X8_512:597			XD_PAGE_512(xd_card);598			xd_card->addr_cycle = 3;599			xd_card->zone_cnt = 2;600			xd_card->capacity = 64000;601			break;602		case XD_64M_X8_512:603			XD_PAGE_512(xd_card);604			xd_card->addr_cycle = 4;605			xd_card->zone_cnt = 4;606			xd_card->capacity = 128000;607			break;608		case XD_128M_X8_512:609			XD_PAGE_512(xd_card);610			xd_card->addr_cycle = 4;611			xd_card->zone_cnt = 8;612			xd_card->capacity = 256000;613			break;614		case XD_256M_X8_512:615			XD_PAGE_512(xd_card);616			xd_card->addr_cycle = 4;617			xd_card->zone_cnt = 16;618			xd_card->capacity = 512000;619			break;620		case XD_512M_X8:621			XD_PAGE_512(xd_card);622			xd_card->addr_cycle = 4;623			xd_card->zone_cnt = 32;624			xd_card->capacity = 1024000;625			break;626		case XD_1G_X8_512:627			XD_PAGE_512(xd_card);628			xd_card->addr_cycle = 4;629			xd_card->zone_cnt = 64;630			xd_card->capacity = 2048000;631			break;632		case XD_2G_X8_512:633			XD_PAGE_512(xd_card);634			xd_card->addr_cycle = 4;635			xd_card->zone_cnt = 128;636			xd_card->capacity = 4096000;637			break;638		default:639			continue;640		}641 642		/* Confirm timing setting */643		for (j = 0; j < 10; j++) {644			retval = xd_read_id(chip, READ_ID, id_buf, 4);645			if (retval != STATUS_SUCCESS)646				return STATUS_FAIL;647 648			if (id_buf[1] != xd_card->device_code)649				break;650		}651 652		if (j == 10)653			break;654	}655 656	if (i == 4) {657		xd_card->block_shift = 0;658		xd_card->page_off = 0;659		xd_card->addr_cycle = 0;660		xd_card->capacity = 0;661 662		return STATUS_FAIL;663	}664 665	retval = xd_read_id(chip, READ_XD_ID, id_buf, 4);666	if (retval != STATUS_SUCCESS)667		return STATUS_FAIL;668	dev_dbg(rtsx_dev(chip), "READ_XD_ID: 0x%x 0x%x 0x%x 0x%x\n",669		id_buf[0], id_buf[1], id_buf[2], id_buf[3]);670	if (id_buf[2] != XD_ID_CODE)671		return STATUS_FAIL;672 673	/* Search CIS block */674	for (i = 0; i < 24; i++) {675		u32 page_addr;676 677		if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS)678			return STATUS_FAIL;679 680		page_addr = (u32)i << xd_card->block_shift;681 682		for (j = 0; j < 3; j++) {683			retval = xd_read_redundant(chip, page_addr, redunt, 11);684			if (retval == STATUS_SUCCESS)685				break;686		}687		if (j == 3)688			continue;689 690		if (redunt[BLOCK_STATUS] != XD_GBLK)691			continue;692 693		j = 0;694		if (redunt[PAGE_STATUS] != XD_GPG) {695			for (j = 1; j <= 8; j++) {696				retval = xd_read_redundant(chip, page_addr + j,697							   redunt, 11);698				if (retval == STATUS_SUCCESS) {699					if (redunt[PAGE_STATUS] == XD_GPG)700						break;701				}702			}703 704			if (j == 9)705				break;706		}707 708		/* Check CIS data */709		if (redunt[BLOCK_STATUS] == XD_GBLK &&710		    (redunt[PARITY] & XD_BA1_ALL0)) {711			u8 buf[10];712 713			page_addr += j;714 715			retval = xd_read_cis(chip, page_addr, buf, 10);716			if (retval != STATUS_SUCCESS)717				return STATUS_FAIL;718 719			if (buf[0] == 0x01 && buf[1] == 0x03 &&720			    buf[2] == 0xD9 &&721			    buf[3] == 0x01 && buf[4] == 0xFF &&722			    buf[5] == 0x18 && buf[6] == 0x02 &&723			    buf[7] == 0xDF && buf[8] == 0x01 &&724			    buf[9] == 0x20) {725				xd_card->cis_block = (u16)i;726			}727		}728 729		break;730	}731 732	dev_dbg(rtsx_dev(chip), "CIS block: 0x%x\n", xd_card->cis_block);733	if (xd_card->cis_block == 0xFFFF)734		return STATUS_FAIL;735 736	chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity;737 738	return STATUS_SUCCESS;739}740 741static int xd_check_data_blank(u8 *redunt)742{743	int i;744 745	for (i = 0; i < 6; i++) {746		if (redunt[PAGE_STATUS + i] != 0xFF)747			return 0;748	}749 750	if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1))751		!= (XD_ECC1_ALL1 | XD_ECC2_ALL1))752		return 0;753 754	for (i = 0; i < 4; i++) {755		if (redunt[RESERVED0 + i] != 0xFF)756			return 0;757	}758 759	return 1;760}761 762static u16 xd_load_log_block_addr(u8 *redunt)763{764	u16 addr = 0xFFFF;765 766	if (redunt[PARITY] & XD_BA1_BA2_EQL)767		addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) |768			redunt[BLOCK_ADDR1_L];769	else if (redunt[PARITY] & XD_BA1_VALID)770		addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) |771			redunt[BLOCK_ADDR1_L];772	else if (redunt[PARITY] & XD_BA2_VALID)773		addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) |774			redunt[BLOCK_ADDR2_L];775 776	return addr;777}778 779static int xd_init_l2p_tbl(struct rtsx_chip *chip)780{781	struct xd_info *xd_card = &chip->xd_card;782	int size, i;783 784	dev_dbg(rtsx_dev(chip), "%s: zone_cnt = %d\n", __func__,785		xd_card->zone_cnt);786 787	if (xd_card->zone_cnt < 1)788		return STATUS_FAIL;789 790	size = xd_card->zone_cnt * sizeof(struct zone_entry);791	dev_dbg(rtsx_dev(chip), "Buffer size for l2p table is %d\n", size);792 793	xd_card->zone = vmalloc(size);794	if (!xd_card->zone)795		return STATUS_ERROR;796 797	for (i = 0; i < xd_card->zone_cnt; i++) {798		xd_card->zone[i].build_flag = 0;799		xd_card->zone[i].l2p_table = NULL;800		xd_card->zone[i].free_table = NULL;801		xd_card->zone[i].get_index = 0;802		xd_card->zone[i].set_index = 0;803		xd_card->zone[i].unused_blk_cnt = 0;804	}805 806	return STATUS_SUCCESS;807}808 809static inline void free_zone(struct zone_entry *zone)810{811	if (!zone)812		return;813 814	zone->build_flag = 0;815	zone->set_index = 0;816	zone->get_index = 0;817	zone->unused_blk_cnt = 0;818	vfree(zone->l2p_table);819	zone->l2p_table = NULL;820	vfree(zone->free_table);821	zone->free_table = NULL;822}823 824static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk)825{826	struct xd_info *xd_card = &chip->xd_card;827	struct zone_entry *zone;828	int zone_no;829 830	zone_no = (int)phy_blk >> 10;831	if (zone_no >= xd_card->zone_cnt) {832		dev_dbg(rtsx_dev(chip), "Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n",833			zone_no, xd_card->zone_cnt);834		return;835	}836	zone = &xd_card->zone[zone_no];837 838	if (!zone->free_table) {839		if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS)840			return;841	}842 843	if (zone->set_index >= XD_FREE_TABLE_CNT ||844	    zone->set_index < 0) {845		free_zone(zone);846		dev_dbg(rtsx_dev(chip), "Set unused block fail, invalid set_index\n");847		return;848	}849 850	dev_dbg(rtsx_dev(chip), "Set unused block to index %d\n",851		zone->set_index);852 853	zone->free_table[zone->set_index++] = (u16)(phy_blk & 0x3ff);854	if (zone->set_index >= XD_FREE_TABLE_CNT)855		zone->set_index = 0;856	zone->unused_blk_cnt++;857}858 859static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no)860{861	struct xd_info *xd_card = &chip->xd_card;862	struct zone_entry *zone;863	u32 phy_blk;864 865	if (zone_no >= xd_card->zone_cnt) {866		dev_dbg(rtsx_dev(chip), "Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n",867			zone_no, xd_card->zone_cnt);868		return BLK_NOT_FOUND;869	}870	zone = &xd_card->zone[zone_no];871 872	if (zone->unused_blk_cnt == 0 ||873	    zone->set_index == zone->get_index) {874		free_zone(zone);875		dev_dbg(rtsx_dev(chip), "Get unused block fail, no unused block available\n");876		return BLK_NOT_FOUND;877	}878	if (zone->get_index >= XD_FREE_TABLE_CNT || zone->get_index < 0) {879		free_zone(zone);880		dev_dbg(rtsx_dev(chip), "Get unused block fail, invalid get_index\n");881		return BLK_NOT_FOUND;882	}883 884	dev_dbg(rtsx_dev(chip), "Get unused block from index %d\n",885		zone->get_index);886 887	phy_blk = zone->free_table[zone->get_index];888	zone->free_table[zone->get_index++] = 0xFFFF;889	if (zone->get_index >= XD_FREE_TABLE_CNT)890		zone->get_index = 0;891	zone->unused_blk_cnt--;892 893	phy_blk += ((u32)(zone_no) << 10);894	return phy_blk;895}896 897static void xd_set_l2p_tbl(struct rtsx_chip *chip,898			   int zone_no, u16 log_off, u16 phy_off)899{900	struct xd_info *xd_card = &chip->xd_card;901	struct zone_entry *zone;902 903	zone = &xd_card->zone[zone_no];904	zone->l2p_table[log_off] = phy_off;905}906 907static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off)908{909	struct xd_info *xd_card = &chip->xd_card;910	struct zone_entry *zone;911	int retval;912 913	zone = &xd_card->zone[zone_no];914	if (zone->l2p_table[log_off] == 0xFFFF) {915		u32 phy_blk = 0;916		int i;917 918#ifdef XD_DELAY_WRITE919		retval = xd_delay_write(chip);920		if (retval != STATUS_SUCCESS) {921			dev_dbg(rtsx_dev(chip), "In %s, delay write fail!\n",922				__func__);923			return BLK_NOT_FOUND;924		}925#endif926 927		if (zone->unused_blk_cnt <= 0) {928			dev_dbg(rtsx_dev(chip), "No unused block!\n");929			return BLK_NOT_FOUND;930		}931 932		for (i = 0; i < zone->unused_blk_cnt; i++) {933			phy_blk = xd_get_unused_block(chip, zone_no);934			if (phy_blk == BLK_NOT_FOUND) {935				dev_dbg(rtsx_dev(chip), "No unused block available!\n");936				return BLK_NOT_FOUND;937			}938 939			retval = xd_init_page(chip, phy_blk, log_off,940					      0, xd_card->page_off + 1);941			if (retval == STATUS_SUCCESS)942				break;943		}944		if (i >= zone->unused_blk_cnt) {945			dev_dbg(rtsx_dev(chip), "No good unused block available!\n");946			return BLK_NOT_FOUND;947		}948 949		xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF));950		return phy_blk;951	}952 953	return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10);954}955 956int reset_xd_card(struct rtsx_chip *chip)957{958	struct xd_info *xd_card = &chip->xd_card;959	int retval;960 961	memset(xd_card, 0, sizeof(struct xd_info));962 963	xd_card->block_shift = 0;964	xd_card->page_off = 0;965	xd_card->addr_cycle = 0;966	xd_card->capacity = 0;967	xd_card->zone_cnt = 0;968	xd_card->cis_block = 0xFFFF;969	xd_card->delay_write.delay_write_flag = 0;970 971	retval = enable_card_clock(chip, XD_CARD);972	if (retval != STATUS_SUCCESS)973		return STATUS_FAIL;974 975	retval = reset_xd(chip);976	if (retval != STATUS_SUCCESS)977		return STATUS_FAIL;978 979	retval = xd_init_l2p_tbl(chip);980	if (retval != STATUS_SUCCESS)981		return STATUS_FAIL;982 983	return STATUS_SUCCESS;984}985 986static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk)987{988	struct xd_info *xd_card = &chip->xd_card;989	int retval;990	u32 page_addr;991	u8 reg = 0;992 993	dev_dbg(rtsx_dev(chip), "mark block 0x%x as bad block\n", phy_blk);994 995	if (phy_blk == BLK_NOT_FOUND)996		return STATUS_FAIL;997 998	rtsx_init_cmd(chip);999 1000	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);1001	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK);1002	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF);1003	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF);1004	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF);1005	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF);1006	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF);1007	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF);1008	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF);1009	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF);1010 1011	page_addr = phy_blk << xd_card->block_shift;1012 1013	xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);1014 1015	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF,1016		     xd_card->page_off + 1);1017 1018	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,1019		     XD_TRANSFER_START | XD_WRITE_REDUNDANT);1020	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1021		     XD_TRANSFER_END, XD_TRANSFER_END);1022 1023	retval = rtsx_send_cmd(chip, XD_CARD, 500);1024	if (retval < 0) {1025		rtsx_clear_xd_error(chip);1026		rtsx_read_register(chip, XD_DAT, &reg);1027		if (reg & PROGRAM_ERROR)1028			xd_set_err_code(chip, XD_PRG_ERROR);1029		else1030			xd_set_err_code(chip, XD_TO_ERROR);1031		return STATUS_FAIL;1032	}1033 1034	return STATUS_SUCCESS;1035}1036 1037static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk,1038			u16 logoff, u8 start_page, u8 end_page)1039{1040	struct xd_info *xd_card = &chip->xd_card;1041	int retval;1042	u32 page_addr;1043	u8 reg = 0;1044 1045	dev_dbg(rtsx_dev(chip), "Init block 0x%x\n", phy_blk);1046 1047	if (start_page > end_page)1048		return STATUS_FAIL;1049	if (phy_blk == BLK_NOT_FOUND)1050		return STATUS_FAIL;1051 1052	rtsx_init_cmd(chip);1053 1054	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF);1055	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF);1056	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H,1057		     0xFF, (u8)(logoff >> 8));1058	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff);1059 1060	page_addr = (phy_blk << xd_card->block_shift) + start_page;1061 1062	xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);1063 1064	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG,1065		     XD_BA_TRANSFORM, XD_BA_TRANSFORM);1066 1067	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT,1068		     0xFF, (end_page - start_page));1069 1070	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,1071		     0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT);1072	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1073		     XD_TRANSFER_END, XD_TRANSFER_END);1074 1075	retval = rtsx_send_cmd(chip, XD_CARD, 500);1076	if (retval < 0) {1077		rtsx_clear_xd_error(chip);1078		rtsx_read_register(chip, XD_DAT, &reg);1079		if (reg & PROGRAM_ERROR) {1080			xd_mark_bad_block(chip, phy_blk);1081			xd_set_err_code(chip, XD_PRG_ERROR);1082		} else {1083			xd_set_err_code(chip, XD_TO_ERROR);1084		}1085		return STATUS_FAIL;1086	}1087 1088	return STATUS_SUCCESS;1089}1090 1091static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk,1092			u8 start_page, u8 end_page)1093{1094	struct xd_info *xd_card = &chip->xd_card;1095	u32 old_page, new_page;1096	u8 i, reg = 0;1097	int retval;1098 1099	dev_dbg(rtsx_dev(chip), "Copy page from block 0x%x to block 0x%x\n",1100		old_blk, new_blk);1101 1102	if (start_page > end_page)1103		return STATUS_FAIL;1104 1105	if (old_blk == BLK_NOT_FOUND || new_blk == BLK_NOT_FOUND)1106		return STATUS_FAIL;1107 1108	old_page = (old_blk << xd_card->block_shift) + start_page;1109	new_page = (new_blk << xd_card->block_shift) + start_page;1110 1111	XD_CLR_BAD_NEWBLK(xd_card);1112 1113	retval = rtsx_write_register(chip, CARD_DATA_SOURCE, 0x01,1114				     PINGPONG_BUFFER);1115	if (retval)1116		return retval;1117 1118	for (i = start_page; i < end_page; i++) {1119		if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {1120			rtsx_clear_xd_error(chip);1121			xd_set_err_code(chip, XD_NO_CARD);1122			return STATUS_FAIL;1123		}1124 1125		rtsx_init_cmd(chip);1126 1127		xd_assign_phy_addr(chip, old_page, XD_RW_ADDR);1128 1129		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);1130		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,1131			     XD_AUTO_CHK_DATA_STATUS, 0);1132		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,1133			     XD_TRANSFER_START | XD_READ_PAGES);1134		rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1135			     XD_TRANSFER_END, XD_TRANSFER_END);1136 1137		retval = rtsx_send_cmd(chip, XD_CARD, 500);1138		if (retval < 0) {1139			rtsx_clear_xd_error(chip);1140			reg = 0;1141			rtsx_read_register(chip, XD_CTL, &reg);1142			if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) {1143				mdelay(100);1144 1145				if (detect_card_cd(chip,1146						   XD_CARD) != STATUS_SUCCESS) {1147					xd_set_err_code(chip, XD_NO_CARD);1148					return STATUS_FAIL;1149				}1150 1151				if (((reg & XD_ECC1_ERROR) &&1152				     (reg & XD_ECC1_UNCORRECTABLE)) ||1153				    ((reg & XD_ECC2_ERROR) &&1154				     (reg & XD_ECC2_UNCORRECTABLE))) {1155					rtsx_write_register(chip,1156							    XD_PAGE_STATUS,1157							    0xFF,1158							    XD_BPG);1159					rtsx_write_register(chip,1160							    XD_BLOCK_STATUS,1161							    0xFF,1162							    XD_GBLK);1163					XD_SET_BAD_OLDBLK(xd_card);1164					dev_dbg(rtsx_dev(chip), "old block 0x%x ecc error\n",1165						old_blk);1166				}1167			} else {1168				xd_set_err_code(chip, XD_TO_ERROR);1169				return STATUS_FAIL;1170			}1171		}1172 1173		if (XD_CHK_BAD_OLDBLK(xd_card))1174			rtsx_clear_xd_error(chip);1175 1176		rtsx_init_cmd(chip);1177 1178		xd_assign_phy_addr(chip, new_page, XD_RW_ADDR);1179		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);1180		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,1181			     XD_TRANSFER_START | XD_WRITE_PAGES);1182		rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1183			     XD_TRANSFER_END, XD_TRANSFER_END);1184 1185		retval = rtsx_send_cmd(chip, XD_CARD, 300);1186		if (retval < 0) {1187			rtsx_clear_xd_error(chip);1188			reg = 0;1189			rtsx_read_register(chip, XD_DAT, &reg);1190			if (reg & PROGRAM_ERROR) {1191				xd_mark_bad_block(chip, new_blk);1192				xd_set_err_code(chip, XD_PRG_ERROR);1193				XD_SET_BAD_NEWBLK(xd_card);1194			} else {1195				xd_set_err_code(chip, XD_TO_ERROR);1196			}1197			return STATUS_FAIL;1198		}1199 1200		old_page++;1201		new_page++;1202	}1203 1204	return STATUS_SUCCESS;1205}1206 1207static int xd_reset_cmd(struct rtsx_chip *chip)1208{1209	int retval;1210	u8 *ptr;1211 1212	rtsx_init_cmd(chip);1213 1214	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,1215		     0xFF, XD_TRANSFER_START | XD_RESET);1216	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1217		     XD_TRANSFER_END, XD_TRANSFER_END);1218	rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);1219	rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);1220 1221	retval = rtsx_send_cmd(chip, XD_CARD, 100);1222	if (retval < 0)1223		return STATUS_FAIL;1224 1225	ptr = rtsx_get_cmd_data(chip) + 1;1226	if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY))1227		return STATUS_SUCCESS;1228 1229	return STATUS_FAIL;1230}1231 1232static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk)1233{1234	struct xd_info *xd_card = &chip->xd_card;1235	u32 page_addr;1236	u8 reg = 0, *ptr;1237	int i, retval;1238 1239	if (phy_blk == BLK_NOT_FOUND)1240		return STATUS_FAIL;1241 1242	page_addr = phy_blk << xd_card->block_shift;1243 1244	for (i = 0; i < 3; i++) {1245		rtsx_init_cmd(chip);1246 1247		xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR);1248 1249		rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,1250			     XD_TRANSFER_START | XD_ERASE);1251		rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1252			     XD_TRANSFER_END, XD_TRANSFER_END);1253		rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);1254 1255		retval = rtsx_send_cmd(chip, XD_CARD, 250);1256		if (retval < 0) {1257			rtsx_clear_xd_error(chip);1258			rtsx_read_register(chip, XD_DAT, &reg);1259			if (reg & PROGRAM_ERROR) {1260				xd_mark_bad_block(chip, phy_blk);1261				xd_set_err_code(chip, XD_PRG_ERROR);1262				return STATUS_FAIL;1263			}1264			xd_set_err_code(chip, XD_ERASE_FAIL);1265			retval = xd_reset_cmd(chip);1266			if (retval != STATUS_SUCCESS)1267				return STATUS_FAIL;1268			continue;1269		}1270 1271		ptr = rtsx_get_cmd_data(chip) + 1;1272		if (*ptr & PROGRAM_ERROR) {1273			xd_mark_bad_block(chip, phy_blk);1274			xd_set_err_code(chip, XD_PRG_ERROR);1275			return STATUS_FAIL;1276		}1277 1278		return STATUS_SUCCESS;1279	}1280 1281	xd_mark_bad_block(chip, phy_blk);1282	xd_set_err_code(chip, XD_ERASE_FAIL);1283	return STATUS_FAIL;1284}1285 1286static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)1287{1288	struct xd_info *xd_card = &chip->xd_card;1289	struct zone_entry *zone;1290	int retval;1291	u32 start, end, i;1292	u16 max_logoff, cur_fst_page_logoff;1293	u16 cur_lst_page_logoff, ent_lst_page_logoff;1294	u8 redunt[11];1295 1296	dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, zone_no);1297 1298	if (!xd_card->zone) {1299		retval = xd_init_l2p_tbl(chip);1300		if (retval != STATUS_SUCCESS)1301			return retval;1302	}1303 1304	if (xd_card->zone[zone_no].build_flag) {1305		dev_dbg(rtsx_dev(chip), "l2p table of zone %d has been built\n",1306			zone_no);1307		return STATUS_SUCCESS;1308	}1309 1310	zone = &xd_card->zone[zone_no];1311 1312	if (!zone->l2p_table) {1313		zone->l2p_table = vmalloc(2000);1314		if (!zone->l2p_table)1315			goto build_fail;1316	}1317	memset((u8 *)(zone->l2p_table), 0xff, 2000);1318 1319	if (!zone->free_table) {1320		zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2);1321		if (!zone->free_table)1322			goto build_fail;1323	}1324	memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2);1325 1326	if (zone_no == 0) {1327		if (xd_card->cis_block == 0xFFFF)1328			start = 0;1329		else1330			start = xd_card->cis_block + 1;1331		if (XD_CHK_4MB(xd_card)) {1332			end = 0x200;1333			max_logoff = 499;1334		} else {1335			end = 0x400;1336			max_logoff = 999;1337		}1338	} else {1339		start = (u32)(zone_no) << 10;1340		end = (u32)(zone_no + 1) << 10;1341		max_logoff = 999;1342	}1343 1344	dev_dbg(rtsx_dev(chip), "start block 0x%x, end block 0x%x\n",1345		start, end);1346 1347	zone->set_index = 0;1348	zone->get_index = 0;1349	zone->unused_blk_cnt = 0;1350 1351	for (i = start; i < end; i++) {1352		u32 page_addr = i << xd_card->block_shift;1353		u32 phy_block;1354 1355		retval = xd_read_redundant(chip, page_addr, redunt, 11);1356		if (retval != STATUS_SUCCESS)1357			continue;1358 1359		if (redunt[BLOCK_STATUS] != 0xFF) {1360			dev_dbg(rtsx_dev(chip), "bad block\n");1361			continue;1362		}1363 1364		if (xd_check_data_blank(redunt)) {1365			dev_dbg(rtsx_dev(chip), "blank block\n");1366			xd_set_unused_block(chip, i);1367			continue;1368		}1369 1370		cur_fst_page_logoff = xd_load_log_block_addr(redunt);1371		if (cur_fst_page_logoff == 0xFFFF ||1372		    cur_fst_page_logoff > max_logoff) {1373			retval = xd_erase_block(chip, i);1374			if (retval == STATUS_SUCCESS)1375				xd_set_unused_block(chip, i);1376			continue;1377		}1378 1379		if (zone_no == 0 && cur_fst_page_logoff == 0 &&1380		    redunt[PAGE_STATUS] != XD_GPG)1381			XD_SET_MBR_FAIL(xd_card);1382 1383		if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) {1384			zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF);1385			continue;1386		}1387 1388		phy_block = zone->l2p_table[cur_fst_page_logoff] +1389			((u32)((zone_no) << 10));1390 1391		page_addr = ((i + 1) << xd_card->block_shift) - 1;1392 1393		retval = xd_read_redundant(chip, page_addr, redunt, 11);1394		if (retval != STATUS_SUCCESS)1395			continue;1396 1397		cur_lst_page_logoff = xd_load_log_block_addr(redunt);1398		if (cur_lst_page_logoff == cur_fst_page_logoff) {1399			int m;1400 1401			page_addr = ((phy_block + 1) <<1402				xd_card->block_shift) - 1;1403 1404			for (m = 0; m < 3; m++) {1405				retval = xd_read_redundant(chip, page_addr,1406							   redunt, 11);1407				if (retval == STATUS_SUCCESS)1408					break;1409			}1410 1411			if (m == 3) {1412				zone->l2p_table[cur_fst_page_logoff] =1413					(u16)(i & 0x3FF);1414				retval = xd_erase_block(chip, phy_block);1415				if (retval == STATUS_SUCCESS)1416					xd_set_unused_block(chip, phy_block);1417				continue;1418			}1419 1420			ent_lst_page_logoff = xd_load_log_block_addr(redunt);1421			if (ent_lst_page_logoff != cur_fst_page_logoff) {1422				zone->l2p_table[cur_fst_page_logoff] =1423					(u16)(i & 0x3FF);1424				retval = xd_erase_block(chip, phy_block);1425				if (retval == STATUS_SUCCESS)1426					xd_set_unused_block(chip, phy_block);1427				continue;1428			} else {1429				retval = xd_erase_block(chip, i);1430				if (retval == STATUS_SUCCESS)1431					xd_set_unused_block(chip, i);1432			}1433		} else {1434			retval = xd_erase_block(chip, i);1435			if (retval == STATUS_SUCCESS)1436				xd_set_unused_block(chip, i);1437		}1438	}1439 1440	if (XD_CHK_4MB(xd_card))1441		end = 500;1442	else1443		end = 1000;1444 1445	i = 0;1446	for (start = 0; start < end; start++) {1447		if (zone->l2p_table[start] == 0xFFFF)1448			i++;1449	}1450 1451	dev_dbg(rtsx_dev(chip), "Block count %d, invalid L2P entry %d\n",1452		end, i);1453	dev_dbg(rtsx_dev(chip), "Total unused block: %d\n",1454		zone->unused_blk_cnt);1455 1456	if ((zone->unused_blk_cnt - i) < 1)1457		chip->card_wp |= XD_CARD;1458 1459	zone->build_flag = 1;1460 1461	return STATUS_SUCCESS;1462 1463build_fail:1464	vfree(zone->l2p_table);1465	zone->l2p_table = NULL;1466	vfree(zone->free_table);1467	zone->free_table = NULL;1468 1469	return STATUS_FAIL;1470}1471 1472static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd)1473{1474	int retval;1475 1476	rtsx_init_cmd(chip);1477 1478	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd);1479	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,1480		     XD_TRANSFER_START | XD_SET_CMD);1481	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1482		     XD_TRANSFER_END, XD_TRANSFER_END);1483 1484	retval = rtsx_send_cmd(chip, XD_CARD, 200);1485	if (retval < 0)1486		return STATUS_FAIL;1487 1488	return STATUS_SUCCESS;1489}1490 1491static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk,1492				  u32 log_blk, u8 start_page, u8 end_page,1493				  u8 *buf, unsigned int *index,1494				  unsigned int *offset)1495{1496	struct xd_info *xd_card = &chip->xd_card;1497	u32 page_addr, new_blk;1498	u16 log_off;1499	u8 reg_val, page_cnt;1500	int zone_no, retval, i;1501 1502	if (start_page > end_page)1503		goto status_fail;1504 1505	page_cnt = end_page - start_page;1506	zone_no = (int)(log_blk / 1000);1507	log_off = (u16)(log_blk % 1000);1508 1509	if ((phy_blk & 0x3FF) == 0x3FF) {1510		for (i = 0; i < 256; i++) {1511			page_addr = ((u32)i) << xd_card->block_shift;1512 1513			retval = xd_read_redundant(chip, page_addr, NULL, 0);1514			if (retval == STATUS_SUCCESS)1515				break;1516 1517			if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {1518				xd_set_err_code(chip, XD_NO_CARD);1519				goto status_fail;1520			}1521		}1522	}1523 1524	page_addr = (phy_blk << xd_card->block_shift) + start_page;1525 1526	rtsx_init_cmd(chip);1527 1528	xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);1529	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE);1530	rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);1531	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);1532	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,1533		     XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);1534 1535	trans_dma_enable(chip->srb->sc_data_direction, chip,1536			 page_cnt * 512, DMA_512);1537 1538	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,1539		     XD_TRANSFER_START | XD_READ_PAGES);1540	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1541		     XD_TRANSFER_END | XD_PPB_EMPTY,1542		     XD_TRANSFER_END | XD_PPB_EMPTY);1543 1544	rtsx_send_cmd_no_wait(chip);1545 1546	retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512,1547					    scsi_sg_count(chip->srb),1548					    index, offset, DMA_FROM_DEVICE,1549					    chip->xd_timeout);1550	if (retval < 0) {1551		rtsx_clear_xd_error(chip);1552 1553		if (retval == -ETIMEDOUT) {1554			xd_set_err_code(chip, XD_TO_ERROR);1555			goto status_fail;1556		} else {1557			goto fail;1558		}1559	}1560 1561	return STATUS_SUCCESS;1562 1563fail:1564	retval = rtsx_read_register(chip, XD_PAGE_STATUS, &reg_val);1565	if (retval)1566		return retval;1567 1568	if (reg_val !=  XD_GPG)1569		xd_set_err_code(chip, XD_PRG_ERROR);1570 1571	retval = rtsx_read_register(chip, XD_CTL, &reg_val);1572	if (retval)1573		return retval;1574 1575	if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) ==1576				(XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) ||1577		((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) ==1578			(XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) {1579		wait_timeout(100);1580 1581		if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {1582			xd_set_err_code(chip, XD_NO_CARD);1583			goto status_fail;1584		}1585 1586		xd_set_err_code(chip, XD_ECC_ERROR);1587 1588		new_blk = xd_get_unused_block(chip, zone_no);1589		if (new_blk == NO_NEW_BLK) {1590			XD_CLR_BAD_OLDBLK(xd_card);1591			goto status_fail;1592		}1593 1594		retval = xd_copy_page(chip, phy_blk, new_blk, 0,1595				      xd_card->page_off + 1);1596		if (retval != STATUS_SUCCESS) {1597			if (!XD_CHK_BAD_NEWBLK(xd_card)) {1598				retval = xd_erase_block(chip, new_blk);1599				if (retval == STATUS_SUCCESS)1600					xd_set_unused_block(chip, new_blk);1601			} else {1602				XD_CLR_BAD_NEWBLK(xd_card);1603			}1604			XD_CLR_BAD_OLDBLK(xd_card);1605			goto status_fail;1606		}1607		xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));1608		xd_erase_block(chip, phy_blk);1609		xd_mark_bad_block(chip, phy_blk);1610		XD_CLR_BAD_OLDBLK(xd_card);1611	}1612 1613status_fail:1614	return STATUS_FAIL;1615}1616 1617static int xd_finish_write(struct rtsx_chip *chip,1618			   u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)1619{1620	struct xd_info *xd_card = &chip->xd_card;1621	int retval, zone_no;1622	u16 log_off;1623 1624	dev_dbg(rtsx_dev(chip), "old_blk = 0x%x, ", old_blk);1625	dev_dbg(rtsx_dev(chip),	"new_blk = 0x%x, ", new_blk);1626	dev_dbg(rtsx_dev(chip), "log_blk = 0x%x\n", log_blk);1627 1628	if (page_off > xd_card->page_off)1629		return STATUS_FAIL;1630 1631	zone_no = (int)(log_blk / 1000);1632	log_off = (u16)(log_blk % 1000);1633 1634	if (old_blk == BLK_NOT_FOUND) {1635		retval = xd_init_page(chip, new_blk, log_off,1636				      page_off, xd_card->page_off + 1);1637		if (retval != STATUS_SUCCESS) {1638			retval = xd_erase_block(chip, new_blk);1639			if (retval == STATUS_SUCCESS)1640				xd_set_unused_block(chip, new_blk);1641			return STATUS_FAIL;1642		}1643	} else {1644		retval = xd_copy_page(chip, old_blk, new_blk,1645				      page_off, xd_card->page_off + 1);1646		if (retval != STATUS_SUCCESS) {1647			if (!XD_CHK_BAD_NEWBLK(xd_card)) {1648				retval = xd_erase_block(chip, new_blk);1649				if (retval == STATUS_SUCCESS)1650					xd_set_unused_block(chip, new_blk);1651			}1652			XD_CLR_BAD_NEWBLK(xd_card);1653			return STATUS_FAIL;1654		}1655 1656		retval = xd_erase_block(chip, old_blk);1657		if (retval == STATUS_SUCCESS) {1658			if (XD_CHK_BAD_OLDBLK(xd_card)) {1659				xd_mark_bad_block(chip, old_blk);1660				XD_CLR_BAD_OLDBLK(xd_card);1661			} else {1662				xd_set_unused_block(chip, old_blk);1663			}1664		} else {1665			xd_set_err_code(chip, XD_NO_ERROR);1666			XD_CLR_BAD_OLDBLK(xd_card);1667		}1668	}1669 1670	xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));1671 1672	return STATUS_SUCCESS;1673}1674 1675static int xd_prepare_write(struct rtsx_chip *chip,1676			    u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)1677{1678	int retval;1679 1680	dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n",1681		__func__, old_blk, new_blk, log_blk, (int)page_off);1682 1683	if (page_off) {1684		retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off);1685		if (retval != STATUS_SUCCESS)1686			return STATUS_FAIL;1687	}1688 1689	return STATUS_SUCCESS;1690}1691 1692static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,1693				   u32 new_blk, u32 log_blk, u8 start_page,1694				   u8 end_page, u8 *buf, unsigned int *index,1695				   unsigned int *offset)1696{1697	struct xd_info *xd_card = &chip->xd_card;1698	u32 page_addr;1699	int zone_no, retval;1700	u16 log_off;1701	u8 page_cnt, reg_val;1702 1703	dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",1704		__func__, old_blk, new_blk, log_blk);1705 1706	if (start_page > end_page)1707		goto status_fail;1708 1709	page_cnt = end_page - start_page;1710	zone_no = (int)(log_blk / 1000);1711	log_off = (u16)(log_blk % 1000);1712 1713	page_addr = (new_blk << xd_card->block_shift) + start_page;1714 1715	retval = xd_send_cmd(chip, READ1_1);1716	if (retval != STATUS_SUCCESS)1717		goto status_fail;1718 1719	rtsx_init_cmd(chip);1720 1721	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H,1722		     0xFF, (u8)(log_off >> 8));1723	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off);1724	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK);1725	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);1726 1727	xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);1728 1729	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM,1730		     XD_BA_TRANSFORM);1731	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);1732	rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);1733 1734	trans_dma_enable(chip->srb->sc_data_direction, chip,1735			 page_cnt * 512, DMA_512);1736 1737	rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,1738		     0xFF, XD_TRANSFER_START | XD_WRITE_PAGES);1739	rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,1740		     XD_TRANSFER_END, XD_TRANSFER_END);1741 1742	rtsx_send_cmd_no_wait(chip);1743 1744	retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512,1745					    scsi_sg_count(chip->srb),1746					    index, offset, DMA_TO_DEVICE, chip->xd_timeout);1747	if (retval < 0) {1748		rtsx_clear_xd_error(chip);1749 1750		if (retval == -ETIMEDOUT) {1751			xd_set_err_code(chip, XD_TO_ERROR);1752			goto status_fail;1753		} else {1754			goto fail;1755		}1756	}1757 1758	if (end_page == (xd_card->page_off + 1)) {1759		xd_card->delay_write.delay_write_flag = 0;1760 1761		if (old_blk != BLK_NOT_FOUND) {1762			retval = xd_erase_block(chip, old_blk);1763			if (retval == STATUS_SUCCESS) {1764				if (XD_CHK_BAD_OLDBLK(xd_card)) {1765					xd_mark_bad_block(chip, old_blk);1766					XD_CLR_BAD_OLDBLK(xd_card);1767				} else {1768					xd_set_unused_block(chip, old_blk);1769				}1770			} else {1771				xd_set_err_code(chip, XD_NO_ERROR);1772				XD_CLR_BAD_OLDBLK(xd_card);1773			}1774		}1775		xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));1776	}1777 1778	return STATUS_SUCCESS;1779 1780fail:1781	retval = rtsx_read_register(chip, XD_DAT, &reg_val);1782	if (retval)1783		return retval;1784	if (reg_val & PROGRAM_ERROR) {1785		xd_set_err_code(chip, XD_PRG_ERROR);1786		xd_mark_bad_block(chip, new_blk);1787	}1788 1789status_fail:1790	return STATUS_FAIL;1791}1792 1793#ifdef XD_DELAY_WRITE1794int xd_delay_write(struct rtsx_chip *chip)1795{1796	struct xd_info *xd_card = &chip->xd_card;1797	struct xd_delay_write_tag *delay_write = &xd_card->delay_write;1798	int retval;1799 1800	if (delay_write->delay_write_flag) {1801		retval = xd_switch_clock(chip);1802		if (retval != STATUS_SUCCESS)1803			return STATUS_FAIL;1804 1805		delay_write->delay_write_flag = 0;1806		retval = xd_finish_write(chip,1807					 delay_write->old_phyblock,1808					 delay_write->new_phyblock,1809					 delay_write->logblock,1810					 delay_write->pageoff);1811		if (retval != STATUS_SUCCESS)1812			return STATUS_FAIL;1813	}1814 1815	return STATUS_SUCCESS;1816}1817#endif1818 1819int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,1820	  u32 start_sector, u16 sector_cnt)1821{1822	struct xd_info *xd_card = &chip->xd_card;1823	unsigned int lun = SCSI_LUN(srb);1824#ifdef XD_DELAY_WRITE1825	struct xd_delay_write_tag *delay_write = &xd_card->delay_write;1826#endif1827	int retval, zone_no;1828	unsigned int index = 0, offset = 0;1829	u32 log_blk, old_blk = 0, new_blk = 0;1830	u16 log_off, total_sec_cnt = sector_cnt;1831	u8 start_page, end_page = 0, page_cnt;1832	u8 *ptr;1833 1834	xd_set_err_code(chip, XD_NO_ERROR);1835 1836	xd_card->cleanup_counter = 0;1837 1838	dev_dbg(rtsx_dev(chip), "%s: scsi_sg_count = %d\n", __func__,1839		scsi_sg_count(srb));1840 1841	ptr = (u8 *)scsi_sglist(srb);1842 1843	retval = xd_switch_clock(chip);1844	if (retval != STATUS_SUCCESS)1845		return STATUS_FAIL;1846 1847	if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {1848		chip->card_fail |= XD_CARD;1849		set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);1850		return STATUS_FAIL;1851	}1852 1853	log_blk = start_sector >> xd_card->block_shift;1854	start_page = (u8)start_sector & xd_card->page_off;1855	zone_no = (int)(log_blk / 1000);1856	log_off = (u16)(log_blk % 1000);1857 1858	if (xd_card->zone[zone_no].build_flag == 0) {1859		retval = xd_build_l2p_tbl(chip, zone_no);1860		if (retval != STATUS_SUCCESS) {1861			chip->card_fail |= XD_CARD;1862			set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);1863			return STATUS_FAIL;1864		}1865	}1866 1867	if (srb->sc_data_direction == DMA_TO_DEVICE) {1868#ifdef XD_DELAY_WRITE1869		if (delay_write->delay_write_flag &&1870		    delay_write->logblock == log_blk &&1871		    start_page > delay_write->pageoff) {1872			delay_write->delay_write_flag = 0;1873			if (delay_write->old_phyblock != BLK_NOT_FOUND) {1874				retval = xd_copy_page(chip,1875						      delay_write->old_phyblock,1876						      delay_write->new_phyblock,1877						      delay_write->pageoff,1878						      start_page);1879				if (retval != STATUS_SUCCESS) {1880					set_sense_type(chip, lun,1881						       SENSE_TYPE_MEDIA_WRITE_ERR);1882					return STATUS_FAIL;1883				}1884			}1885			old_blk = delay_write->old_phyblock;1886			new_blk = delay_write->new_phyblock;1887		} else if (delay_write->delay_write_flag &&1888				(delay_write->logblock == log_blk) &&1889				(start_page == delay_write->pageoff)) {1890			delay_write->delay_write_flag = 0;1891			old_blk = delay_write->old_phyblock;1892			new_blk = delay_write->new_phyblock;1893		} else {1894			retval = xd_delay_write(chip);1895			if (retval != STATUS_SUCCESS) {1896				set_sense_type(chip, lun,1897					       SENSE_TYPE_MEDIA_WRITE_ERR);1898				return STATUS_FAIL;1899			}1900#endif1901			old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);1902			new_blk  = xd_get_unused_block(chip, zone_no);1903			if (old_blk == BLK_NOT_FOUND ||1904			    new_blk == BLK_NOT_FOUND) {1905				set_sense_type(chip, lun,1906					       SENSE_TYPE_MEDIA_WRITE_ERR);1907				return STATUS_FAIL;1908			}1909 1910			retval = xd_prepare_write(chip, old_blk, new_blk,1911						  log_blk, start_page);1912			if (retval != STATUS_SUCCESS) {1913				if (detect_card_cd(chip, XD_CARD) !=1914					STATUS_SUCCESS) {1915					set_sense_type(chip, lun,1916						       SENSE_TYPE_MEDIA_NOT_PRESENT);1917					return STATUS_FAIL;1918				}1919				set_sense_type(chip, lun,1920					       SENSE_TYPE_MEDIA_WRITE_ERR);1921				return STATUS_FAIL;1922			}1923#ifdef XD_DELAY_WRITE1924		}1925#endif1926	} else {1927#ifdef XD_DELAY_WRITE1928		retval = xd_delay_write(chip);1929		if (retval != STATUS_SUCCESS) {1930			if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {1931				set_sense_type(chip, lun,1932					       SENSE_TYPE_MEDIA_NOT_PRESENT);1933				return STATUS_FAIL;1934			}1935			set_sense_type(chip, lun,1936				       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);1937			return STATUS_FAIL;1938		}1939#endif1940 1941		old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);1942		if (old_blk == BLK_NOT_FOUND) {1943			set_sense_type(chip, lun,1944				       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);1945			return STATUS_FAIL;1946		}1947	}1948 1949	dev_dbg(rtsx_dev(chip), "old_blk = 0x%x\n", old_blk);1950 1951	while (total_sec_cnt) {1952		if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {1953			chip->card_fail |= XD_CARD;1954			set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);1955			return STATUS_FAIL;1956		}1957 1958		if ((start_page + total_sec_cnt) > (xd_card->page_off + 1))1959			end_page = xd_card->page_off + 1;1960		else1961			end_page = start_page + (u8)total_sec_cnt;1962 1963		page_cnt = end_page - start_page;1964		if (srb->sc_data_direction == DMA_FROM_DEVICE) {1965			retval = xd_read_multiple_pages(chip, old_blk, log_blk,1966							start_page, end_page,1967							ptr, &index, &offset);1968			if (retval != STATUS_SUCCESS) {1969				set_sense_type(chip, lun,1970					       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);1971				return STATUS_FAIL;1972			}1973		} else {1974			retval = xd_write_multiple_pages(chip, old_blk,1975							 new_blk, log_blk,1976							 start_page, end_page,1977							 ptr, &index, &offset);1978			if (retval != STATUS_SUCCESS) {1979				set_sense_type(chip, lun,1980					       SENSE_TYPE_MEDIA_WRITE_ERR);1981				return STATUS_FAIL;1982			}1983		}1984 1985		total_sec_cnt -= page_cnt;1986		if (scsi_sg_count(srb) == 0)1987			ptr += page_cnt * 512;1988 1989		if (total_sec_cnt == 0)1990			break;1991 1992		log_blk++;1993		zone_no = (int)(log_blk / 1000);1994		log_off = (u16)(log_blk % 1000);1995 1996		if (xd_card->zone[zone_no].build_flag == 0) {1997			retval = xd_build_l2p_tbl(chip, zone_no);1998			if (retval != STATUS_SUCCESS) {1999				chip->card_fail |= XD_CARD;2000				set_sense_type(chip, lun,2001					       SENSE_TYPE_MEDIA_NOT_PRESENT);2002				return STATUS_FAIL;2003			}2004		}2005 2006		old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);2007		if (old_blk == BLK_NOT_FOUND) {2008			if (srb->sc_data_direction == DMA_FROM_DEVICE)2009				set_sense_type(chip, lun,2010					       SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);2011			else2012				set_sense_type(chip, lun,2013					       SENSE_TYPE_MEDIA_WRITE_ERR);2014 2015			return STATUS_FAIL;2016		}2017 2018		if (srb->sc_data_direction == DMA_TO_DEVICE) {2019			new_blk = xd_get_unused_block(chip, zone_no);2020			if (new_blk == BLK_NOT_FOUND) {2021				set_sense_type(chip, lun,2022					       SENSE_TYPE_MEDIA_WRITE_ERR);2023				return STATUS_FAIL;2024			}2025		}2026 2027		start_page = 0;2028	}2029 2030	if (srb->sc_data_direction == DMA_TO_DEVICE &&2031	    (end_page != (xd_card->page_off + 1))) {2032#ifdef XD_DELAY_WRITE2033		delay_write->delay_write_flag = 1;2034		delay_write->old_phyblock = old_blk;2035		delay_write->new_phyblock = new_blk;2036		delay_write->logblock = log_blk;2037		delay_write->pageoff = end_page;2038#else2039		if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {2040			chip->card_fail |= XD_CARD;2041			set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);2042			return STATUS_FAIL;2043		}2044 2045		retval = xd_finish_write(chip, old_blk, new_blk,2046					 log_blk, end_page);2047		if (retval != STATUS_SUCCESS) {2048			if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {2049				set_sense_type(chip, lun,2050					       SENSE_TYPE_MEDIA_NOT_PRESENT);2051				return STATUS_FAIL;2052			}2053			set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);2054			return STATUS_FAIL;2055		}2056#endif2057	}2058 2059	scsi_set_resid(srb, 0);2060 2061	return STATUS_SUCCESS;2062}2063 2064void xd_free_l2p_tbl(struct rtsx_chip *chip)2065{2066	struct xd_info *xd_card = &chip->xd_card;2067	int i = 0;2068 2069	if (xd_card->zone) {2070		for (i = 0; i < xd_card->zone_cnt; i++) {2071			vfree(xd_card->zone[i].l2p_table);2072			xd_card->zone[i].l2p_table = NULL;2073			vfree(xd_card->zone[i].free_table);2074			xd_card->zone[i].free_table = NULL;2075		}2076		vfree(xd_card->zone);2077		xd_card->zone = NULL;2078	}2079}2080 2081void xd_cleanup_work(struct rtsx_chip *chip)2082{2083#ifdef XD_DELAY_WRITE2084	struct xd_info *xd_card = &chip->xd_card;2085 2086	if (xd_card->delay_write.delay_write_flag) {2087		dev_dbg(rtsx_dev(chip), "xD: delay write\n");2088		xd_delay_write(chip);2089		xd_card->cleanup_counter = 0;2090	}2091#endif2092}2093 2094int xd_power_off_card3v3(struct rtsx_chip *chip)2095{2096	int retval;2097 2098	retval = disable_card_clock(chip, XD_CARD);2099	if (retval != STATUS_SUCCESS)2100		return STATUS_FAIL;2101 2102	retval = rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0);2103	if (retval)2104		return retval;2105 2106	if (!chip->ft2_fast_mode) {2107		retval = card_power_off(chip, XD_CARD);2108		if (retval != STATUS_SUCCESS)2109			return STATUS_FAIL;2110 2111		wait_timeout(50);2112	}2113 2114	if (chip->asic_code) {2115		retval = xd_pull_ctl_disable(chip);2116		if (retval != STATUS_SUCCESS)2117			return STATUS_FAIL;2118	} else {2119		retval = rtsx_write_register(chip, FPGA_PULL_CTL, 0xFF, 0xDF);2120		if (retval)2121			return retval;2122	}2123 2124	return STATUS_SUCCESS;2125}2126 2127int release_xd_card(struct rtsx_chip *chip)2128{2129	struct xd_info *xd_card = &chip->xd_card;2130	int retval;2131 2132	chip->card_ready &= ~XD_CARD;2133	chip->card_fail &= ~XD_CARD;2134	chip->card_wp &= ~XD_CARD;2135 2136	xd_card->delay_write.delay_write_flag = 0;2137 2138	xd_free_l2p_tbl(chip);2139 2140	retval = xd_power_off_card3v3(chip);2141	if (retval != STATUS_SUCCESS)2142		return STATUS_FAIL;2143 2144	return STATUS_SUCCESS;2145}2146