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