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
 838        for (i = 0; i < 4; i++) {
 839                if (redunt[RESERVED0 + i] != 0xFF)
 840                        return 0;
 841        }
 842
 843        return 1;
 844}
 845
 846static u16 xd_load_log_block_addr(u8 *redunt)
 847{
 848        u16 addr = 0xFFFF;
 849
 850        if (redunt[PARITY] & XD_BA1_BA2_EQL)
 851                addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) |
 852                        redunt[BLOCK_ADDR1_L];
 853        else if (redunt[PARITY] & XD_BA1_VALID)
 854                addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) |
 855                        redunt[BLOCK_ADDR1_L];
 856        else if (redunt[PARITY] & XD_BA2_VALID)
 857                addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) |
 858                        redunt[BLOCK_ADDR2_L];
 859
 860        return addr;
 861}
 862
 863static int xd_init_l2p_tbl(struct rtsx_chip *chip)
 864{
 865        struct xd_info *xd_card = &(chip->xd_card);
 866        int size, i;
 867
 868        dev_dbg(rtsx_dev(chip), "xd_init_l2p_tbl: zone_cnt = %d\n",
 869                xd_card->zone_cnt);
 870
 871        if (xd_card->zone_cnt < 1) {
 872                rtsx_trace(chip);
 873                return STATUS_FAIL;
 874        }
 875
 876        size = xd_card->zone_cnt * sizeof(struct zone_entry);
 877        dev_dbg(rtsx_dev(chip), "Buffer size for l2p table is %d\n", size);
 878
 879        xd_card->zone = vmalloc(size);
 880        if (!xd_card->zone) {
 881                rtsx_trace(chip);
 882                return STATUS_ERROR;
 883        }
 884
 885        for (i = 0; i < xd_card->zone_cnt; i++) {
 886                xd_card->zone[i].build_flag = 0;
 887                xd_card->zone[i].l2p_table = NULL;
 888                xd_card->zone[i].free_table = NULL;
 889                xd_card->zone[i].get_index = 0;
 890                xd_card->zone[i].set_index = 0;
 891                xd_card->zone[i].unused_blk_cnt = 0;
 892        }
 893
 894        return STATUS_SUCCESS;
 895}
 896
 897static inline void free_zone(struct zone_entry *zone)
 898{
 899        if (!zone)
 900                return;
 901
 902        zone->build_flag = 0;
 903        zone->set_index = 0;
 904        zone->get_index = 0;
 905        zone->unused_blk_cnt = 0;
 906        vfree(zone->l2p_table);
 907        zone->l2p_table = NULL;
 908        vfree(zone->free_table);
 909        zone->free_table = NULL;
 910}
 911
 912static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk)
 913{
 914        struct xd_info *xd_card = &(chip->xd_card);
 915        struct zone_entry *zone;
 916        int zone_no;
 917
 918        zone_no = (int)phy_blk >> 10;
 919        if (zone_no >= xd_card->zone_cnt) {
 920                dev_dbg(rtsx_dev(chip), "Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n",
 921                        zone_no, xd_card->zone_cnt);
 922                return;
 923        }
 924        zone = &(xd_card->zone[zone_no]);
 925
 926        if (zone->free_table == NULL) {
 927                if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS)
 928                        return;
 929        }
 930
 931        if ((zone->set_index >= XD_FREE_TABLE_CNT)
 932                        || (zone->set_index < 0)) {
 933                free_zone(zone);
 934                dev_dbg(rtsx_dev(chip), "Set unused block fail, invalid set_index\n");
 935                return;
 936        }
 937
 938        dev_dbg(rtsx_dev(chip), "Set unused block to index %d\n",
 939                zone->set_index);
 940
 941        zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff);
 942        if (zone->set_index >= XD_FREE_TABLE_CNT)
 943                zone->set_index = 0;
 944        zone->unused_blk_cnt++;
 945}
 946
 947static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no)
 948{
 949        struct xd_info *xd_card = &(chip->xd_card);
 950        struct zone_entry *zone;
 951        u32 phy_blk;
 952
 953        if (zone_no >= xd_card->zone_cnt) {
 954                dev_dbg(rtsx_dev(chip), "Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n",
 955                        zone_no, xd_card->zone_cnt);
 956                return BLK_NOT_FOUND;
 957        }
 958        zone = &(xd_card->zone[zone_no]);
 959
 960        if ((zone->unused_blk_cnt == 0) ||
 961                (zone->set_index == zone->get_index)) {
 962                free_zone(zone);
 963                dev_dbg(rtsx_dev(chip), "Get unused block fail, no unused block available\n");
 964                return BLK_NOT_FOUND;
 965        }
 966        if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) {
 967                free_zone(zone);
 968                dev_dbg(rtsx_dev(chip), "Get unused block fail, invalid get_index\n");
 969                return BLK_NOT_FOUND;
 970        }
 971
 972        dev_dbg(rtsx_dev(chip), "Get unused block from index %d\n",
 973                zone->get_index);
 974
 975        phy_blk = zone->free_table[zone->get_index];
 976        zone->free_table[zone->get_index++] = 0xFFFF;
 977        if (zone->get_index >= XD_FREE_TABLE_CNT)
 978                zone->get_index = 0;
 979        zone->unused_blk_cnt--;
 980
 981        phy_blk += ((u32)(zone_no) << 10);
 982        return phy_blk;
 983}
 984
 985static void xd_set_l2p_tbl(struct rtsx_chip *chip,
 986                        int zone_no, u16 log_off, u16 phy_off)
 987{
 988        struct xd_info *xd_card = &(chip->xd_card);
 989        struct zone_entry *zone;
 990
 991        zone = &(xd_card->zone[zone_no]);
 992        zone->l2p_table[log_off] = phy_off;
 993}
 994
 995static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off)
 996{
 997        struct xd_info *xd_card = &(chip->xd_card);
 998        struct zone_entry *zone;
 999        int retval;
1000
1001        zone = &(xd_card->zone[zone_no]);
1002        if (zone->l2p_table[log_off] == 0xFFFF) {
1003                u32 phy_blk = 0;
1004                int i;
1005
1006#ifdef XD_DELAY_WRITE
1007                retval = xd_delay_write(chip);
1008                if (retval != STATUS_SUCCESS) {
1009                        dev_dbg(rtsx_dev(chip), "In xd_get_l2p_tbl, delay write fail!\n");
1010                        return BLK_NOT_FOUND;
1011                }
1012#endif
1013
1014                if (zone->unused_blk_cnt <= 0) {
1015                        dev_dbg(rtsx_dev(chip), "No unused block!\n");
1016                        return BLK_NOT_FOUND;
1017                }
1018
1019                for (i = 0; i < zone->unused_blk_cnt; i++) {
1020                        phy_blk = xd_get_unused_block(chip, zone_no);
1021                        if (phy_blk == BLK_NOT_FOUND) {
1022                                dev_dbg(rtsx_dev(chip), "No unused block available!\n");
1023                                return BLK_NOT_FOUND;
1024                        }
1025
1026                        retval = xd_init_page(chip, phy_blk, log_off,
1027                                        0, xd_card->page_off + 1);
1028                        if (retval == STATUS_SUCCESS)
1029                                break;
1030                }
1031                if (i >= zone->unused_blk_cnt) {
1032                        dev_dbg(rtsx_dev(chip), "No good unused block available!\n");
1033                        return BLK_NOT_FOUND;
1034                }
1035
1036                xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF));
1037                return phy_blk;
1038        }
1039
1040        return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10);
1041}
1042
1043int reset_xd_card(struct rtsx_chip *chip)
1044{
1045        struct xd_info *xd_card = &(chip->xd_card);
1046        int retval;
1047
1048        memset(xd_card, 0, sizeof(struct xd_info));
1049
1050        xd_card->block_shift = 0;
1051        xd_card->page_off = 0;
1052        xd_card->addr_cycle = 0;
1053        xd_card->capacity = 0;
1054        xd_card->zone_cnt = 0;
1055        xd_card->cis_block = 0xFFFF;
1056        xd_card->delay_write.delay_write_flag = 0;
1057
1058        retval = enable_card_clock(chip, XD_CARD);
1059        if (retval != STATUS_SUCCESS) {
1060                rtsx_trace(chip);
1061                return STATUS_FAIL;
1062        }
1063
1064        retval = reset_xd(chip);
1065        if (retval != STATUS_SUCCESS) {
1066                rtsx_trace(chip);
1067                return STATUS_FAIL;
1068        }
1069
1070        retval = xd_init_l2p_tbl(chip);
1071        if (retval != STATUS_SUCCESS) {
1072                rtsx_trace(chip);
1073                return STATUS_FAIL;
1074        }
1075
1076        return STATUS_SUCCESS;
1077}
1078
1079static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk)
1080{
1081        struct xd_info *xd_card = &(chip->xd_card);
1082        int retval;
1083        u32 page_addr;
1084        u8 reg = 0;
1085
1086        dev_dbg(rtsx_dev(chip), "mark block 0x%x as bad block\n", phy_blk);
1087
1088        if (phy_blk == BLK_NOT_FOUND) {
1089                rtsx_trace(chip);
1090                return STATUS_FAIL;
1091        }
1092
1093        rtsx_init_cmd(chip);
1094
1095        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);
1096        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK);
1097        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF);
1098        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF);
1099        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF);
1100        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF);
1101        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF);
1102        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF);
1103        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF);
1104        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF);
1105
1106        page_addr = phy_blk << xd_card->block_shift;
1107
1108        xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
1109
1110        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF,
1111                xd_card->page_off + 1);
1112
1113        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
1114                XD_TRANSFER_START | XD_WRITE_REDUNDANT);
1115        rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1116                XD_TRANSFER_END, XD_TRANSFER_END);
1117
1118        retval = rtsx_send_cmd(chip, XD_CARD, 500);
1119        if (retval < 0) {
1120                rtsx_clear_xd_error(chip);
1121                rtsx_read_register(chip, XD_DAT, &reg);
1122                if (reg & PROGRAM_ERROR)
1123                        xd_set_err_code(chip, XD_PRG_ERROR);
1124                else
1125                        xd_set_err_code(chip, XD_TO_ERROR);
1126                rtsx_trace(chip);
1127                return STATUS_FAIL;
1128        }
1129
1130        return STATUS_SUCCESS;
1131}
1132
1133static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk,
1134                        u16 logoff, u8 start_page, u8 end_page)
1135{
1136        struct xd_info *xd_card = &(chip->xd_card);
1137        int retval;
1138        u32 page_addr;
1139        u8 reg = 0;
1140
1141        dev_dbg(rtsx_dev(chip), "Init block 0x%x\n", phy_blk);
1142
1143        if (start_page > end_page) {
1144                rtsx_trace(chip);
1145                return STATUS_FAIL;
1146        }
1147        if (phy_blk == BLK_NOT_FOUND) {
1148                rtsx_trace(chip);
1149                return STATUS_FAIL;
1150        }
1151
1152        rtsx_init_cmd(chip);
1153
1154        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF);
1155        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF);
1156        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H,
1157                0xFF, (u8)(logoff >> 8));
1158        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff);
1159
1160        page_addr = (phy_blk << xd_card->block_shift) + start_page;
1161
1162        xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
1163
1164        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG,
1165                XD_BA_TRANSFORM, XD_BA_TRANSFORM);
1166
1167        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT,
1168                0xFF, (end_page - start_page));
1169
1170        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,
1171                0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT);
1172        rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1173                XD_TRANSFER_END, XD_TRANSFER_END);
1174
1175        retval = rtsx_send_cmd(chip, XD_CARD, 500);
1176        if (retval < 0) {
1177                rtsx_clear_xd_error(chip);
1178                rtsx_read_register(chip, XD_DAT, &reg);
1179                if (reg & PROGRAM_ERROR) {
1180                        xd_mark_bad_block(chip, phy_blk);
1181                        xd_set_err_code(chip, XD_PRG_ERROR);
1182                } else {
1183                        xd_set_err_code(chip, XD_TO_ERROR);
1184                }
1185                rtsx_trace(chip);
1186                return STATUS_FAIL;
1187        }
1188
1189        return STATUS_SUCCESS;
1190}
1191
1192static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk,
1193                        u8 start_page, u8 end_page)
1194{
1195        struct xd_info *xd_card = &(chip->xd_card);
1196        u32 old_page, new_page;
1197        u8 i, reg = 0;
1198        int retval;
1199
1200        dev_dbg(rtsx_dev(chip), "Copy page from block 0x%x to block 0x%x\n",
1201                old_blk, new_blk);
1202
1203        if (start_page > end_page) {
1204                rtsx_trace(chip);
1205                return STATUS_FAIL;
1206        }
1207
1208        if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) {
1209                rtsx_trace(chip);
1210                return STATUS_FAIL;
1211        }
1212
1213        old_page = (old_blk << xd_card->block_shift) + start_page;
1214        new_page = (new_blk << xd_card->block_shift) + start_page;
1215
1216        XD_CLR_BAD_NEWBLK(xd_card);
1217
1218        retval = rtsx_write_register(chip, CARD_DATA_SOURCE, 0x01,
1219                                     PINGPONG_BUFFER);
1220        if (retval) {
1221                rtsx_trace(chip);
1222                return retval;
1223        }
1224
1225        for (i = start_page; i < end_page; i++) {
1226                if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
1227                        rtsx_clear_xd_error(chip);
1228                        xd_set_err_code(chip, XD_NO_CARD);
1229                        rtsx_trace(chip);
1230                        return STATUS_FAIL;
1231                }
1232
1233                rtsx_init_cmd(chip);
1234
1235                xd_assign_phy_addr(chip, old_page, XD_RW_ADDR);
1236
1237                rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
1238                rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,
1239                        XD_AUTO_CHK_DATA_STATUS, 0);
1240                rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
1241                        XD_TRANSFER_START | XD_READ_PAGES);
1242                rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1243                        XD_TRANSFER_END, XD_TRANSFER_END);
1244
1245                retval = rtsx_send_cmd(chip, XD_CARD, 500);
1246                if (retval < 0) {
1247                        rtsx_clear_xd_error(chip);
1248                        reg = 0;
1249                        rtsx_read_register(chip, XD_CTL, &reg);
1250                        if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) {
1251                                wait_timeout(100);
1252
1253                                if (detect_card_cd(chip,
1254                                        XD_CARD) != STATUS_SUCCESS) {
1255                                        xd_set_err_code(chip, XD_NO_CARD);
1256                                        rtsx_trace(chip);
1257                                        return STATUS_FAIL;
1258                                }
1259
1260                                if (((reg & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) ==
1261                                                (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
1262                                        || ((reg & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) ==
1263                                                (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) {
1264                                        rtsx_write_register(chip,
1265                                                        XD_PAGE_STATUS, 0xFF,
1266                                                        XD_BPG);
1267                                        rtsx_write_register(chip,
1268                                                        XD_BLOCK_STATUS, 0xFF,
1269                                                        XD_GBLK);
1270                                        XD_SET_BAD_OLDBLK(xd_card);
1271                                        dev_dbg(rtsx_dev(chip), "old block 0x%x ecc error\n",
1272                                                old_blk);
1273                                }
1274                        } else {
1275                                xd_set_err_code(chip, XD_TO_ERROR);
1276                                rtsx_trace(chip);
1277                                return STATUS_FAIL;
1278                        }
1279                }
1280
1281                if (XD_CHK_BAD_OLDBLK(xd_card))
1282                        rtsx_clear_xd_error(chip);
1283
1284                rtsx_init_cmd(chip);
1285
1286                xd_assign_phy_addr(chip, new_page, XD_RW_ADDR);
1287                rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1);
1288                rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
1289                             XD_TRANSFER_START | XD_WRITE_PAGES);
1290                rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1291                        XD_TRANSFER_END, XD_TRANSFER_END);
1292
1293                retval = rtsx_send_cmd(chip, XD_CARD, 300);
1294                if (retval < 0) {
1295                        rtsx_clear_xd_error(chip);
1296                        reg = 0;
1297                        rtsx_read_register(chip, XD_DAT, &reg);
1298                        if (reg & PROGRAM_ERROR) {
1299                                xd_mark_bad_block(chip, new_blk);
1300                                xd_set_err_code(chip, XD_PRG_ERROR);
1301                                XD_SET_BAD_NEWBLK(xd_card);
1302                        } else {
1303                                xd_set_err_code(chip, XD_TO_ERROR);
1304                        }
1305                        rtsx_trace(chip);
1306                        return STATUS_FAIL;
1307                }
1308
1309                old_page++;
1310                new_page++;
1311        }
1312
1313        return STATUS_SUCCESS;
1314}
1315
1316static int xd_reset_cmd(struct rtsx_chip *chip)
1317{
1318        int retval;
1319        u8 *ptr;
1320
1321        rtsx_init_cmd(chip);
1322
1323        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,
1324                0xFF, XD_TRANSFER_START | XD_RESET);
1325        rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1326                XD_TRANSFER_END, XD_TRANSFER_END);
1327        rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
1328        rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);
1329
1330        retval = rtsx_send_cmd(chip, XD_CARD, 100);
1331        if (retval < 0) {
1332                rtsx_trace(chip);
1333                return STATUS_FAIL;
1334        }
1335
1336        ptr = rtsx_get_cmd_data(chip) + 1;
1337        if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY))
1338                return STATUS_SUCCESS;
1339
1340        rtsx_trace(chip);
1341        return STATUS_FAIL;
1342}
1343
1344static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk)
1345{
1346        struct xd_info *xd_card = &(chip->xd_card);
1347        u32 page_addr;
1348        u8 reg = 0, *ptr;
1349        int i, retval;
1350
1351        if (phy_blk == BLK_NOT_FOUND) {
1352                rtsx_trace(chip);
1353                return STATUS_FAIL;
1354        }
1355
1356        page_addr = phy_blk << xd_card->block_shift;
1357
1358        for (i = 0; i < 3; i++) {
1359                rtsx_init_cmd(chip);
1360
1361                xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR);
1362
1363                rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
1364                        XD_TRANSFER_START | XD_ERASE);
1365                rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1366                        XD_TRANSFER_END, XD_TRANSFER_END);
1367                rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0);
1368
1369                retval = rtsx_send_cmd(chip, XD_CARD, 250);
1370                if (retval < 0) {
1371                        rtsx_clear_xd_error(chip);
1372                        rtsx_read_register(chip, XD_DAT, &reg);
1373                        if (reg & PROGRAM_ERROR) {
1374                                xd_mark_bad_block(chip, phy_blk);
1375                                xd_set_err_code(chip, XD_PRG_ERROR);
1376                                rtsx_trace(chip);
1377                                return STATUS_FAIL;
1378                        }
1379                        xd_set_err_code(chip, XD_ERASE_FAIL);
1380                        retval = xd_reset_cmd(chip);
1381                        if (retval != STATUS_SUCCESS) {
1382                                rtsx_trace(chip);
1383                                return STATUS_FAIL;
1384                        }
1385                        continue;
1386                }
1387
1388                ptr = rtsx_get_cmd_data(chip) + 1;
1389                if (*ptr & PROGRAM_ERROR) {
1390                        xd_mark_bad_block(chip, phy_blk);
1391                        xd_set_err_code(chip, XD_PRG_ERROR);
1392                        rtsx_trace(chip);
1393                        return STATUS_FAIL;
1394                }
1395
1396                return STATUS_SUCCESS;
1397        }
1398
1399        xd_mark_bad_block(chip, phy_blk);
1400        xd_set_err_code(chip, XD_ERASE_FAIL);
1401        rtsx_trace(chip);
1402        return STATUS_FAIL;
1403}
1404
1405
1406static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
1407{
1408        struct xd_info *xd_card = &(chip->xd_card);
1409        struct zone_entry *zone;
1410        int retval;
1411        u32 start, end, i;
1412        u16 max_logoff, cur_fst_page_logoff;
1413        u16 cur_lst_page_logoff, ent_lst_page_logoff;
1414        u8 redunt[11];
1415
1416        dev_dbg(rtsx_dev(chip), "xd_build_l2p_tbl: %d\n", zone_no);
1417
1418        if (xd_card->zone == NULL) {
1419                retval = xd_init_l2p_tbl(chip);
1420                if (retval != STATUS_SUCCESS)
1421                        return retval;
1422        }
1423
1424        if (xd_card->zone[zone_no].build_flag) {
1425                dev_dbg(rtsx_dev(chip), "l2p table of zone %d has been built\n",
1426                        zone_no);
1427                return STATUS_SUCCESS;
1428        }
1429
1430        zone = &(xd_card->zone[zone_no]);
1431
1432        if (zone->l2p_table == NULL) {
1433                zone->l2p_table = vmalloc(2000);
1434                if (!zone->l2p_table) {
1435                        rtsx_trace(chip);
1436                        goto Build_Fail;
1437                }
1438        }
1439        memset((u8 *)(zone->l2p_table), 0xff, 2000);
1440
1441        if (zone->free_table == NULL) {
1442                zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2);
1443                if (!zone->free_table) {
1444                        rtsx_trace(chip);
1445                        goto Build_Fail;
1446                }
1447        }
1448        memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2);
1449
1450        if (zone_no == 0) {
1451                if (xd_card->cis_block == 0xFFFF)
1452                        start = 0;
1453                else
1454                        start = xd_card->cis_block + 1;
1455                if (XD_CHK_4MB(xd_card)) {
1456                        end = 0x200;
1457                        max_logoff = 499;
1458                } else {
1459                        end = 0x400;
1460                        max_logoff = 999;
1461                }
1462        } else {
1463                start = (u32)(zone_no) << 10;
1464                end = (u32)(zone_no + 1) << 10;
1465                max_logoff = 999;
1466        }
1467
1468        dev_dbg(rtsx_dev(chip), "start block 0x%x, end block 0x%x\n",
1469                start, end);
1470
1471        zone->set_index = zone->get_index = 0;
1472        zone->unused_blk_cnt = 0;
1473
1474        for (i = start; i < end; i++) {
1475                u32 page_addr = i << xd_card->block_shift;
1476                u32 phy_block;
1477
1478                retval = xd_read_redundant(chip, page_addr, redunt, 11);
1479                if (retval != STATUS_SUCCESS)
1480                        continue;
1481
1482                if (redunt[BLOCK_STATUS] != 0xFF) {
1483                        dev_dbg(rtsx_dev(chip), "bad block\n");
1484                        continue;
1485                }
1486
1487                if (xd_check_data_blank(redunt)) {
1488                        dev_dbg(rtsx_dev(chip), "blank block\n");
1489                        xd_set_unused_block(chip, i);
1490                        continue;
1491                }
1492
1493                cur_fst_page_logoff = xd_load_log_block_addr(redunt);
1494                if ((cur_fst_page_logoff == 0xFFFF) ||
1495                        (cur_fst_page_logoff > max_logoff)) {
1496                        retval = xd_erase_block(chip, i);
1497                        if (retval == STATUS_SUCCESS)
1498                                xd_set_unused_block(chip, i);
1499                        continue;
1500                }
1501
1502                if ((zone_no == 0) && (cur_fst_page_logoff == 0) &&
1503                        (redunt[PAGE_STATUS] != XD_GPG))
1504                        XD_SET_MBR_FAIL(xd_card);
1505
1506                if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) {
1507                        zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF);
1508                        continue;
1509                }
1510
1511                phy_block = zone->l2p_table[cur_fst_page_logoff] +
1512                        ((u32)((zone_no) << 10));
1513
1514                page_addr = ((i + 1) << xd_card->block_shift) - 1;
1515
1516                retval = xd_read_redundant(chip, page_addr, redunt, 11);
1517                if (retval != STATUS_SUCCESS)
1518                        continue;
1519
1520                cur_lst_page_logoff = xd_load_log_block_addr(redunt);
1521                if (cur_lst_page_logoff == cur_fst_page_logoff) {
1522                        int m;
1523
1524                        page_addr = ((phy_block + 1) <<
1525                                xd_card->block_shift) - 1;
1526
1527                        for (m = 0; m < 3; m++) {
1528                                retval = xd_read_redundant(chip, page_addr,
1529                                                        redunt, 11);
1530                                if (retval == STATUS_SUCCESS)
1531                                        break;
1532                        }
1533
1534                        if (m == 3) {
1535                                zone->l2p_table[cur_fst_page_logoff] =
1536                                        (u16)(i & 0x3FF);
1537                                retval = xd_erase_block(chip, phy_block);
1538                                if (retval == STATUS_SUCCESS)
1539                                        xd_set_unused_block(chip, phy_block);
1540                                continue;
1541                        }
1542
1543                        ent_lst_page_logoff = xd_load_log_block_addr(redunt);
1544                        if (ent_lst_page_logoff != cur_fst_page_logoff) {
1545                                zone->l2p_table[cur_fst_page_logoff] =
1546                                        (u16)(i & 0x3FF);
1547                                retval = xd_erase_block(chip, phy_block);
1548                                if (retval == STATUS_SUCCESS)
1549                                        xd_set_unused_block(chip, phy_block);
1550                                continue;
1551                        } else {
1552                                retval = xd_erase_block(chip, i);
1553                                if (retval == STATUS_SUCCESS)
1554                                        xd_set_unused_block(chip, i);
1555                        }
1556                } else {
1557                        retval = xd_erase_block(chip, i);
1558                        if (retval == STATUS_SUCCESS)
1559                                xd_set_unused_block(chip, i);
1560                }
1561        }
1562
1563        if (XD_CHK_4MB(xd_card))
1564                end = 500;
1565        else
1566                end = 1000;
1567
1568        i = 0;
1569        for (start = 0; start < end; start++) {
1570                if (zone->l2p_table[start] == 0xFFFF)
1571                        i++;
1572        }
1573
1574        dev_dbg(rtsx_dev(chip), "Block count %d, invalid L2P entry %d\n",
1575                end, i);
1576        dev_dbg(rtsx_dev(chip), "Total unused block: %d\n",
1577                zone->unused_blk_cnt);
1578
1579        if ((zone->unused_blk_cnt - i) < 1)
1580                chip->card_wp |= XD_CARD;
1581
1582        zone->build_flag = 1;
1583
1584        return STATUS_SUCCESS;
1585
1586Build_Fail:
1587        vfree(zone->l2p_table);
1588        zone->l2p_table = NULL;
1589        vfree(zone->free_table);
1590        zone->free_table = NULL;
1591
1592        return STATUS_FAIL;
1593}
1594
1595static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd)
1596{
1597        int retval;
1598
1599        rtsx_init_cmd(chip);
1600
1601        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd);
1602        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
1603                XD_TRANSFER_START | XD_SET_CMD);
1604        rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1605                XD_TRANSFER_END, XD_TRANSFER_END);
1606
1607        retval = rtsx_send_cmd(chip, XD_CARD, 200);
1608        if (retval < 0) {
1609                rtsx_trace(chip);
1610                return STATUS_FAIL;
1611        }
1612
1613        return STATUS_SUCCESS;
1614}
1615
1616static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk,
1617                                u32 log_blk, u8 start_page, u8 end_page,
1618                                u8 *buf, unsigned int *index,
1619                                unsigned int *offset)
1620{
1621        struct xd_info *xd_card = &(chip->xd_card);
1622        u32 page_addr, new_blk;
1623        u16 log_off;
1624        u8 reg_val, page_cnt;
1625        int zone_no, retval, i;
1626
1627        if (start_page > end_page) {
1628                rtsx_trace(chip);
1629                return STATUS_FAIL;
1630        }
1631
1632        page_cnt = end_page - start_page;
1633        zone_no = (int)(log_blk / 1000);
1634        log_off = (u16)(log_blk % 1000);
1635
1636        if ((phy_blk & 0x3FF) == 0x3FF) {
1637                for (i = 0; i < 256; i++) {
1638                        page_addr = ((u32)i) << xd_card->block_shift;
1639
1640                        retval = xd_read_redundant(chip, page_addr, NULL, 0);
1641                        if (retval == STATUS_SUCCESS)
1642                                break;
1643
1644                        if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
1645                                xd_set_err_code(chip, XD_NO_CARD);
1646                                rtsx_trace(chip);
1647                                return STATUS_FAIL;
1648                        }
1649                }
1650        }
1651
1652        page_addr = (phy_blk << xd_card->block_shift) + start_page;
1653
1654        rtsx_init_cmd(chip);
1655
1656        xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
1657        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE);
1658        rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
1659        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);
1660        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS,
1661                        XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS);
1662
1663        trans_dma_enable(chip->srb->sc_data_direction, chip,
1664                        page_cnt * 512, DMA_512);
1665
1666        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF,
1667                XD_TRANSFER_START | XD_READ_PAGES);
1668        rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1669                XD_TRANSFER_END | XD_PPB_EMPTY, XD_TRANSFER_END | XD_PPB_EMPTY);
1670
1671        rtsx_send_cmd_no_wait(chip);
1672
1673        retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512,
1674                                        scsi_sg_count(chip->srb),
1675                                        index, offset, DMA_FROM_DEVICE,
1676                                        chip->xd_timeout);
1677        if (retval < 0) {
1678                rtsx_clear_xd_error(chip);
1679
1680                if (retval == -ETIMEDOUT) {
1681                        xd_set_err_code(chip, XD_TO_ERROR);
1682                        rtsx_trace(chip);
1683                        return STATUS_FAIL;
1684                } else {
1685                        rtsx_trace(chip);
1686                        goto Fail;
1687                }
1688        }
1689
1690        return STATUS_SUCCESS;
1691
1692Fail:
1693        retval = rtsx_read_register(chip, XD_PAGE_STATUS, &reg_val);
1694        if (retval) {
1695                rtsx_trace(chip);
1696                return retval;
1697        }
1698
1699        if (reg_val !=  XD_GPG)
1700                xd_set_err_code(chip, XD_PRG_ERROR);
1701
1702        retval = rtsx_read_register(chip, XD_CTL, &reg_val);
1703        if (retval) {
1704                rtsx_trace(chip);
1705                return retval;
1706        }
1707
1708        if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
1709                                == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE))
1710                || ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))
1711                        == (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) {
1712                wait_timeout(100);
1713
1714                if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
1715                        xd_set_err_code(chip, XD_NO_CARD);
1716                        rtsx_trace(chip);
1717                        return STATUS_FAIL;
1718                }
1719
1720                xd_set_err_code(chip, XD_ECC_ERROR);
1721
1722                new_blk = xd_get_unused_block(chip, zone_no);
1723                if (new_blk == NO_NEW_BLK) {
1724                        XD_CLR_BAD_OLDBLK(xd_card);
1725                        rtsx_trace(chip);
1726                        return STATUS_FAIL;
1727                }
1728
1729                retval = xd_copy_page(chip, phy_blk, new_blk, 0,
1730                                xd_card->page_off + 1);
1731                if (retval != STATUS_SUCCESS) {
1732                        if (!XD_CHK_BAD_NEWBLK(xd_card)) {
1733                                retval = xd_erase_block(chip, new_blk);
1734                                if (retval == STATUS_SUCCESS)
1735                                        xd_set_unused_block(chip, new_blk);
1736                        } else {
1737                                XD_CLR_BAD_NEWBLK(xd_card);
1738                        }
1739                        XD_CLR_BAD_OLDBLK(xd_card);
1740                        rtsx_trace(chip);
1741                        return STATUS_FAIL;
1742                }
1743                xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
1744                xd_erase_block(chip, phy_blk);
1745                xd_mark_bad_block(chip, phy_blk);
1746                XD_CLR_BAD_OLDBLK(xd_card);
1747        }
1748
1749        rtsx_trace(chip);
1750        return STATUS_FAIL;
1751}
1752
1753static int xd_finish_write(struct rtsx_chip *chip,
1754                u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)
1755{
1756        struct xd_info *xd_card = &(chip->xd_card);
1757        int retval, zone_no;
1758        u16 log_off;
1759
1760        dev_dbg(rtsx_dev(chip), "xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
1761                old_blk, new_blk, log_blk);
1762
1763        if (page_off > xd_card->page_off) {
1764                rtsx_trace(chip);
1765                return STATUS_FAIL;
1766        }
1767
1768        zone_no = (int)(log_blk / 1000);
1769        log_off = (u16)(log_blk % 1000);
1770
1771        if (old_blk == BLK_NOT_FOUND) {
1772                retval = xd_init_page(chip, new_blk, log_off,
1773                                page_off, xd_card->page_off + 1);
1774                if (retval != STATUS_SUCCESS) {
1775                        retval = xd_erase_block(chip, new_blk);
1776                        if (retval == STATUS_SUCCESS)
1777                                xd_set_unused_block(chip, new_blk);
1778                        rtsx_trace(chip);
1779                        return STATUS_FAIL;
1780                }
1781        } else {
1782                retval = xd_copy_page(chip, old_blk, new_blk,
1783                                page_off, xd_card->page_off + 1);
1784                if (retval != STATUS_SUCCESS) {
1785                        if (!XD_CHK_BAD_NEWBLK(xd_card)) {
1786                                retval = xd_erase_block(chip, new_blk);
1787                                if (retval == STATUS_SUCCESS)
1788                                        xd_set_unused_block(chip, new_blk);
1789                        }
1790                        XD_CLR_BAD_NEWBLK(xd_card);
1791                        rtsx_trace(chip);
1792                        return STATUS_FAIL;
1793                }
1794
1795                retval = xd_erase_block(chip, old_blk);
1796                if (retval == STATUS_SUCCESS) {
1797                        if (XD_CHK_BAD_OLDBLK(xd_card)) {
1798                                xd_mark_bad_block(chip, old_blk);
1799                                XD_CLR_BAD_OLDBLK(xd_card);
1800                        } else {
1801                                xd_set_unused_block(chip, old_blk);
1802                        }
1803                } else {
1804                        xd_set_err_code(chip, XD_NO_ERROR);
1805                        XD_CLR_BAD_OLDBLK(xd_card);
1806                }
1807        }
1808
1809        xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
1810
1811        return STATUS_SUCCESS;
1812}
1813
1814static int xd_prepare_write(struct rtsx_chip *chip,
1815                u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off)
1816{
1817        int retval;
1818
1819        dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n",
1820                __func__, old_blk, new_blk, log_blk, (int)page_off);
1821
1822        if (page_off) {
1823                retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off);
1824                if (retval != STATUS_SUCCESS) {
1825                        rtsx_trace(chip);
1826                        return STATUS_FAIL;
1827                }
1828        }
1829
1830        return STATUS_SUCCESS;
1831}
1832
1833
1834static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
1835                                u32 new_blk, u32 log_blk, u8 start_page,
1836                                u8 end_page, u8 *buf, unsigned int *index,
1837                                unsigned int *offset)
1838{
1839        struct xd_info *xd_card = &(chip->xd_card);
1840        u32 page_addr;
1841        int zone_no, retval;
1842        u16 log_off;
1843        u8 page_cnt, reg_val;
1844
1845        dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
1846                __func__, old_blk, new_blk, log_blk);
1847
1848        if (start_page > end_page) {
1849                rtsx_trace(chip);
1850                return STATUS_FAIL;
1851        }
1852
1853        page_cnt = end_page - start_page;
1854        zone_no = (int)(log_blk / 1000);
1855        log_off = (u16)(log_blk % 1000);
1856
1857        page_addr = (new_blk << xd_card->block_shift) + start_page;
1858
1859        retval = xd_send_cmd(chip, READ1_1);
1860        if (retval != STATUS_SUCCESS) {
1861                rtsx_trace(chip);
1862                return STATUS_FAIL;
1863        }
1864
1865        rtsx_init_cmd(chip);
1866
1867        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H,
1868                0xFF, (u8)(log_off >> 8));
1869        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off);
1870        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK);
1871        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG);
1872
1873        xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR);
1874
1875        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM,
1876                XD_BA_TRANSFORM);
1877        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt);
1878        rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
1879
1880        trans_dma_enable(chip->srb->sc_data_direction, chip,
1881                        page_cnt * 512, DMA_512);
1882
1883        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER,
1884                0xFF, XD_TRANSFER_START | XD_WRITE_PAGES);
1885        rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER,
1886                XD_TRANSFER_END, XD_TRANSFER_END);
1887
1888        rtsx_send_cmd_no_wait(chip);
1889
1890        retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512,
1891                                        scsi_sg_count(chip->srb),
1892                        index, offset, DMA_TO_DEVICE, chip->xd_timeout);
1893        if (retval < 0) {
1894                rtsx_clear_xd_error(chip);
1895
1896                if (retval == -ETIMEDOUT) {
1897                        xd_set_err_code(chip, XD_TO_ERROR);
1898                        rtsx_trace(chip);
1899                        return STATUS_FAIL;
1900                } else {
1901                        rtsx_trace(chip);
1902                        goto Fail;
1903                }
1904        }
1905
1906        if (end_page == (xd_card->page_off + 1)) {
1907                xd_card->delay_write.delay_write_flag = 0;
1908
1909                if (old_blk != BLK_NOT_FOUND) {
1910                        retval = xd_erase_block(chip, old_blk);
1911                        if (retval == STATUS_SUCCESS) {
1912                                if (XD_CHK_BAD_OLDBLK(xd_card)) {
1913                                        xd_mark_bad_block(chip, old_blk);
1914                                        XD_CLR_BAD_OLDBLK(xd_card);
1915                                } else {
1916                                        xd_set_unused_block(chip, old_blk);
1917                                }
1918                        } else {
1919                                xd_set_err_code(chip, XD_NO_ERROR);
1920                                XD_CLR_BAD_OLDBLK(xd_card);
1921                        }
1922                }
1923                xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
1924        }
1925
1926        return STATUS_SUCCESS;
1927
1928Fail:
1929        retval = rtsx_read_register(chip, XD_DAT, &reg_val);
1930        if (retval) {
1931                rtsx_trace(chip);
1932                return retval;
1933        }
1934        if (reg_val & PROGRAM_ERROR) {
1935                xd_set_err_code(chip, XD_PRG_ERROR);
1936                xd_mark_bad_block(chip, new_blk);
1937        }
1938
1939        rtsx_trace(chip);
1940        return STATUS_FAIL;
1941}
1942
1943#ifdef XD_DELAY_WRITE
1944int xd_delay_write(struct rtsx_chip *chip)
1945{
1946        struct xd_info *xd_card = &(chip->xd_card);
1947        struct xd_delay_write_tag *delay_write = &(xd_card->delay_write);
1948        int retval;
1949
1950        if (delay_write->delay_write_flag) {
1951                dev_dbg(rtsx_dev(chip), "xd_delay_write\n");
1952                retval = xd_switch_clock(chip);
1953                if (retval != STATUS_SUCCESS) {
1954                        rtsx_trace(chip);
1955                        return STATUS_FAIL;
1956                }
1957
1958                delay_write->delay_write_flag = 0;
1959                retval = xd_finish_write(chip,
1960                                delay_write->old_phyblock,
1961                                        delay_write->new_phyblock,
1962                                delay_write->logblock, delay_write->pageoff);
1963                if (retval != STATUS_SUCCESS) {
1964                        rtsx_trace(chip);
1965                        return STATUS_FAIL;
1966                }
1967        }
1968
1969        return STATUS_SUCCESS;
1970}
1971#endif
1972
1973int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
1974        u32 start_sector, u16 sector_cnt)
1975{
1976        struct xd_info *xd_card = &(chip->xd_card);
1977        unsigned int lun = SCSI_LUN(srb);
1978#ifdef XD_DELAY_WRITE
1979        struct xd_delay_write_tag *delay_write = &(xd_card->delay_write);
1980#endif
1981        int retval, zone_no;
1982        unsigned int index = 0, offset = 0;
1983        u32 log_blk, old_blk = 0, new_blk = 0;
1984        u16 log_off, total_sec_cnt = sector_cnt;
1985        u8 start_page, end_page = 0, page_cnt;
1986        u8 *ptr;
1987
1988        xd_set_err_code(chip, XD_NO_ERROR);
1989
1990        xd_card->cleanup_counter = 0;
1991
1992        dev_dbg(rtsx_dev(chip), "xd_rw: scsi_sg_count = %d\n",
1993                scsi_sg_count(srb));
1994
1995        ptr = (u8 *)scsi_sglist(srb);
1996
1997        retval = xd_switch_clock(chip);
1998        if (retval != STATUS_SUCCESS) {
1999                rtsx_trace(chip);
2000                return STATUS_FAIL;
2001        }
2002
2003
2004        if (detect_card_cd(chip, XD_CARD) != 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        log_blk = start_sector >> xd_card->block_shift;
2012        start_page = (u8)start_sector & xd_card->page_off;
2013        zone_no = (int)(log_blk / 1000);
2014        log_off = (u16)(log_blk % 1000);
2015
2016        if (xd_card->zone[zone_no].build_flag == 0) {
2017                retval = xd_build_l2p_tbl(chip, zone_no);
2018                if (retval != STATUS_SUCCESS) {
2019                        chip->card_fail |= XD_CARD;
2020                        set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
2021                        rtsx_trace(chip);
2022                        return STATUS_FAIL;
2023                }
2024        }
2025
2026        if (srb->sc_data_direction == DMA_TO_DEVICE) {
2027#ifdef XD_DELAY_WRITE
2028                if (delay_write->delay_write_flag &&
2029                                (delay_write->logblock == log_blk) &&
2030                                (start_page > delay_write->pageoff)) {
2031                        delay_write->delay_write_flag = 0;
2032                        if (delay_write->old_phyblock != BLK_NOT_FOUND) {
2033                                retval = xd_copy_page(chip,
2034                                        delay_write->old_phyblock,
2035                                        delay_write->new_phyblock,
2036                                        delay_write->pageoff, start_page);
2037                                if (retval != STATUS_SUCCESS) {
2038                                        set_sense_type(chip, lun,
2039                                                SENSE_TYPE_MEDIA_WRITE_ERR);
2040                                        rtsx_trace(chip);
2041                                        return STATUS_FAIL;
2042                                }
2043                        }
2044                        old_blk = delay_write->old_phyblock;
2045                        new_blk = delay_write->new_phyblock;
2046                } else if (delay_write->delay_write_flag &&
2047                                (delay_write->logblock == log_blk) &&
2048                                (start_page == delay_write->pageoff)) {
2049                        delay_write->delay_write_flag = 0;
2050                        old_blk = delay_write->old_phyblock;
2051                        new_blk = delay_write->new_phyblock;
2052                } else {
2053                        retval = xd_delay_write(chip);
2054                        if (retval != STATUS_SUCCESS) {
2055                                set_sense_type(chip, lun,
2056                                        SENSE_TYPE_MEDIA_WRITE_ERR);
2057                                rtsx_trace(chip);
2058                                return STATUS_FAIL;
2059                        }
2060#endif
2061                        old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
2062                        new_blk  = xd_get_unused_block(chip, zone_no);
2063                        if ((old_blk == BLK_NOT_FOUND) ||
2064                                (new_blk == BLK_NOT_FOUND)) {
2065                                set_sense_type(chip, lun,
2066                                        SENSE_TYPE_MEDIA_WRITE_ERR);
2067                                rtsx_trace(chip);
2068                                return STATUS_FAIL;
2069                        }
2070
2071                        retval = xd_prepare_write(chip, old_blk, new_blk,
2072                                                log_blk, start_page);
2073                        if (retval != STATUS_SUCCESS) {
2074                                if (detect_card_cd(chip, XD_CARD) !=
2075                                        STATUS_SUCCESS) {
2076                                        set_sense_type(chip, lun,
2077                                                SENSE_TYPE_MEDIA_NOT_PRESENT);
2078                                        rtsx_trace(chip);
2079                                        return STATUS_FAIL;
2080                                }
2081                                set_sense_type(chip, lun,
2082                                        SENSE_TYPE_MEDIA_WRITE_ERR);
2083                                rtsx_trace(chip);
2084                                return STATUS_FAIL;
2085                        }
2086#ifdef XD_DELAY_WRITE
2087                }
2088#endif
2089        } else {
2090#ifdef XD_DELAY_WRITE
2091                retval = xd_delay_write(chip);
2092                if (retval != STATUS_SUCCESS) {
2093                        if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
2094                                set_sense_type(chip, lun,
2095                                        SENSE_TYPE_MEDIA_NOT_PRESENT);
2096                                rtsx_trace(chip);
2097                                return STATUS_FAIL;
2098                        }
2099                        set_sense_type(chip, lun,
2100                                SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
2101                        rtsx_trace(chip);
2102                        return STATUS_FAIL;
2103                }
2104#endif
2105
2106                old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
2107                if (old_blk == BLK_NOT_FOUND) {
2108                        set_sense_type(chip, lun,
2109                                SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
2110                        rtsx_trace(chip);
2111                        return STATUS_FAIL;
2112                }
2113        }
2114
2115        dev_dbg(rtsx_dev(chip), "old_blk = 0x%x\n", old_blk);
2116
2117        while (total_sec_cnt) {
2118                if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
2119                        chip->card_fail |= XD_CARD;
2120                        set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
2121                        rtsx_trace(chip);
2122                        return STATUS_FAIL;
2123                }
2124
2125                if ((start_page + total_sec_cnt) > (xd_card->page_off + 1))
2126                        end_page = xd_card->page_off + 1;
2127                else
2128                        end_page = start_page + (u8)total_sec_cnt;
2129
2130                page_cnt = end_page - start_page;
2131                if (srb->sc_data_direction == DMA_FROM_DEVICE) {
2132                        retval = xd_read_multiple_pages(chip, old_blk, log_blk,
2133                                        start_page, end_page, ptr,
2134                                                        &index, &offset);
2135                        if (retval != STATUS_SUCCESS) {
2136                                set_sense_type(chip, lun,
2137                                        SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
2138                                rtsx_trace(chip);
2139                                return STATUS_FAIL;
2140                        }
2141                } else {
2142                        retval = xd_write_multiple_pages(chip, old_blk,
2143                                                        new_blk, log_blk,
2144                                        start_page, end_page, ptr,
2145                                                        &index, &offset);
2146                        if (retval != STATUS_SUCCESS) {
2147                                set_sense_type(chip, lun,
2148                                        SENSE_TYPE_MEDIA_WRITE_ERR);
2149                                rtsx_trace(chip);
2150                                return STATUS_FAIL;
2151                        }
2152                }
2153
2154                total_sec_cnt -= page_cnt;
2155                if (scsi_sg_count(srb) == 0)
2156                        ptr += page_cnt * 512;
2157
2158                if (total_sec_cnt == 0)
2159                        break;
2160
2161                log_blk++;
2162                zone_no = (int)(log_blk / 1000);
2163                log_off = (u16)(log_blk % 1000);
2164
2165                if (xd_card->zone[zone_no].build_flag == 0) {
2166                        retval = xd_build_l2p_tbl(chip, zone_no);
2167                        if (retval != STATUS_SUCCESS) {
2168                                chip->card_fail |= XD_CARD;
2169                                set_sense_type(chip, lun,
2170                                        SENSE_TYPE_MEDIA_NOT_PRESENT);
2171                                rtsx_trace(chip);
2172                                return STATUS_FAIL;
2173                        }
2174                }
2175
2176                old_blk = xd_get_l2p_tbl(chip, zone_no, log_off);
2177                if (old_blk == BLK_NOT_FOUND) {
2178                        if (srb->sc_data_direction == DMA_FROM_DEVICE)
2179                                set_sense_type(chip, lun,
2180                                        SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
2181                        else
2182                                set_sense_type(chip, lun,
2183                                        SENSE_TYPE_MEDIA_WRITE_ERR);
2184
2185                        rtsx_trace(chip);
2186                        return STATUS_FAIL;
2187                }
2188
2189                if (srb->sc_data_direction == DMA_TO_DEVICE) {
2190                        new_blk = xd_get_unused_block(chip, zone_no);
2191                        if (new_blk == BLK_NOT_FOUND) {
2192                                set_sense_type(chip, lun,
2193                                        SENSE_TYPE_MEDIA_WRITE_ERR);
2194                                rtsx_trace(chip);
2195                                return STATUS_FAIL;
2196                        }
2197                }
2198
2199                start_page = 0;
2200        }
2201
2202        if ((srb->sc_data_direction == DMA_TO_DEVICE) &&
2203                        (end_page != (xd_card->page_off + 1))) {
2204#ifdef XD_DELAY_WRITE
2205                delay_write->delay_write_flag = 1;
2206                delay_write->old_phyblock = old_blk;
2207                delay_write->new_phyblock = new_blk;
2208                delay_write->logblock = log_blk;
2209                delay_write->pageoff = end_page;
2210#else
2211                if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
2212                        chip->card_fail |= XD_CARD;
2213                        set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
2214                        rtsx_trace(chip);
2215                        return STATUS_FAIL;
2216                }
2217
2218                retval = xd_finish_write(chip, old_blk, new_blk,
2219                                        log_blk, end_page);
2220                if (retval != STATUS_SUCCESS) {
2221                        if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
2222                                set_sense_type(chip, lun,
2223                                        SENSE_TYPE_MEDIA_NOT_PRESENT);
2224                                rtsx_trace(chip);
2225                                return STATUS_FAIL;
2226                        }
2227                        set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR);
2228                        rtsx_trace(chip);
2229                        return STATUS_FAIL;
2230                }
2231#endif
2232        }
2233
2234        scsi_set_resid(srb, 0);
2235
2236        return STATUS_SUCCESS;
2237}
2238
2239void xd_free_l2p_tbl(struct rtsx_chip *chip)
2240{
2241        struct xd_info *xd_card = &(chip->xd_card);
2242        int i = 0;
2243
2244        if (xd_card->zone != NULL) {
2245                for (i = 0; i < xd_card->zone_cnt; i++) {
2246                        vfree(xd_card->zone[i].l2p_table);
2247                        xd_card->zone[i].l2p_table = NULL;
2248                        vfree(xd_card->zone[i].free_table);
2249                        xd_card->zone[i].free_table = NULL;
2250                }
2251                vfree(xd_card->zone);
2252                xd_card->zone = NULL;
2253        }
2254}
2255
2256void xd_cleanup_work(struct rtsx_chip *chip)
2257{
2258#ifdef XD_DELAY_WRITE
2259        struct xd_info *xd_card = &(chip->xd_card);
2260
2261        if (xd_card->delay_write.delay_write_flag) {
2262                dev_dbg(rtsx_dev(chip), "xD: delay write\n");
2263                xd_delay_write(chip);
2264                xd_card->cleanup_counter = 0;
2265        }
2266#endif
2267}
2268
2269int xd_power_off_card3v3(struct rtsx_chip *chip)
2270{
2271        int retval;
2272
2273        retval = disable_card_clock(chip, XD_CARD);
2274        if (retval != STATUS_SUCCESS) {
2275                rtsx_trace(chip);
2276                return STATUS_FAIL;
2277        }
2278
2279        retval = rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0);
2280        if (retval) {
2281                rtsx_trace(chip);
2282                return retval;
2283        }
2284
2285        if (!chip->ft2_fast_mode) {
2286                retval = card_power_off(chip, XD_CARD);
2287                if (retval != STATUS_SUCCESS) {
2288                        rtsx_trace(chip);
2289                        return STATUS_FAIL;
2290                }
2291
2292                wait_timeout(50);
2293        }
2294
2295        if (chip->asic_code) {
2296                retval = xd_pull_ctl_disable(chip);
2297                if (retval != STATUS_SUCCESS) {
2298                        rtsx_trace(chip);
2299                        return STATUS_FAIL;
2300                }
2301        } else {
2302                retval = rtsx_write_register(chip, FPGA_PULL_CTL, 0xFF, 0xDF);
2303                if (retval) {
2304                        rtsx_trace(chip);
2305                        return retval;
2306                }
2307        }
2308
2309        return STATUS_SUCCESS;
2310}
2311
2312int release_xd_card(struct rtsx_chip *chip)
2313{
2314        struct xd_info *xd_card = &(chip->xd_card);
2315        int retval;
2316
2317        chip->card_ready &= ~XD_CARD;
2318        chip->card_fail &= ~XD_CARD;
2319        chip->card_wp &= ~XD_CARD;
2320
2321        xd_card->delay_write.delay_write_flag = 0;
2322
2323        xd_free_l2p_tbl(chip);
2324
2325        retval = xd_power_off_card3v3(chip);
2326        if (retval != STATUS_SUCCESS) {
2327                rtsx_trace(chip);
2328                return STATUS_FAIL;
2329        }
2330
2331        return STATUS_SUCCESS;
2332}
2333