linux/drivers/mtd/sm_ftl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright © 2009 - Maxim Levitsky
   4 * SmartMedia/xD translation layer
   5 */
   6
   7#include <linux/kernel.h>
   8#include <linux/module.h>
   9#include <linux/random.h>
  10#include <linux/hdreg.h>
  11#include <linux/kthread.h>
  12#include <linux/freezer.h>
  13#include <linux/sysfs.h>
  14#include <linux/bitops.h>
  15#include <linux/slab.h>
  16#include <linux/mtd/nand_ecc.h>
  17#include "nand/raw/sm_common.h"
  18#include "sm_ftl.h"
  19
  20
  21
  22static struct workqueue_struct *cache_flush_workqueue;
  23
  24static int cache_timeout = 1000;
  25module_param(cache_timeout, int, S_IRUGO);
  26MODULE_PARM_DESC(cache_timeout,
  27        "Timeout (in ms) for cache flush (1000 ms default");
  28
  29static int debug;
  30module_param(debug, int, S_IRUGO | S_IWUSR);
  31MODULE_PARM_DESC(debug, "Debug level (0-2)");
  32
  33
  34/* ------------------- sysfs attributes ---------------------------------- */
  35struct sm_sysfs_attribute {
  36        struct device_attribute dev_attr;
  37        char *data;
  38        int len;
  39};
  40
  41static ssize_t sm_attr_show(struct device *dev, struct device_attribute *attr,
  42                     char *buf)
  43{
  44        struct sm_sysfs_attribute *sm_attr =
  45                container_of(attr, struct sm_sysfs_attribute, dev_attr);
  46
  47        strncpy(buf, sm_attr->data, sm_attr->len);
  48        return sm_attr->len;
  49}
  50
  51
  52#define NUM_ATTRIBUTES 1
  53#define SM_CIS_VENDOR_OFFSET 0x59
  54static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl)
  55{
  56        struct attribute_group *attr_group;
  57        struct attribute **attributes;
  58        struct sm_sysfs_attribute *vendor_attribute;
  59        char *vendor;
  60
  61        vendor = kstrndup(ftl->cis_buffer + SM_CIS_VENDOR_OFFSET,
  62                          SM_SMALL_PAGE - SM_CIS_VENDOR_OFFSET, GFP_KERNEL);
  63        if (!vendor)
  64                goto error1;
  65
  66        /* Initialize sysfs attributes */
  67        vendor_attribute =
  68                kzalloc(sizeof(struct sm_sysfs_attribute), GFP_KERNEL);
  69        if (!vendor_attribute)
  70                goto error2;
  71
  72        sysfs_attr_init(&vendor_attribute->dev_attr.attr);
  73
  74        vendor_attribute->data = vendor;
  75        vendor_attribute->len = strlen(vendor);
  76        vendor_attribute->dev_attr.attr.name = "vendor";
  77        vendor_attribute->dev_attr.attr.mode = S_IRUGO;
  78        vendor_attribute->dev_attr.show = sm_attr_show;
  79
  80
  81        /* Create array of pointers to the attributes */
  82        attributes = kcalloc(NUM_ATTRIBUTES + 1, sizeof(struct attribute *),
  83                                                                GFP_KERNEL);
  84        if (!attributes)
  85                goto error3;
  86        attributes[0] = &vendor_attribute->dev_attr.attr;
  87
  88        /* Finally create the attribute group */
  89        attr_group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
  90        if (!attr_group)
  91                goto error4;
  92        attr_group->attrs = attributes;
  93        return attr_group;
  94error4:
  95        kfree(attributes);
  96error3:
  97        kfree(vendor_attribute);
  98error2:
  99        kfree(vendor);
 100error1:
 101        return NULL;
 102}
 103
 104static void sm_delete_sysfs_attributes(struct sm_ftl *ftl)
 105{
 106        struct attribute **attributes = ftl->disk_attributes->attrs;
 107        int i;
 108
 109        for (i = 0; attributes[i] ; i++) {
 110
 111                struct device_attribute *dev_attr = container_of(attributes[i],
 112                        struct device_attribute, attr);
 113
 114                struct sm_sysfs_attribute *sm_attr =
 115                        container_of(dev_attr,
 116                                struct sm_sysfs_attribute, dev_attr);
 117
 118                kfree(sm_attr->data);
 119                kfree(sm_attr);
 120        }
 121
 122        kfree(ftl->disk_attributes->attrs);
 123        kfree(ftl->disk_attributes);
 124}
 125
 126
 127/* ----------------------- oob helpers -------------------------------------- */
 128
 129static int sm_get_lba(uint8_t *lba)
 130{
 131        /* check fixed bits */
 132        if ((lba[0] & 0xF8) != 0x10)
 133                return -2;
 134
 135        /* check parity - endianness doesn't matter */
 136        if (hweight16(*(uint16_t *)lba) & 1)
 137                return -2;
 138
 139        return (lba[1] >> 1) | ((lba[0] & 0x07) << 7);
 140}
 141
 142
 143/*
 144 * Read LBA associated with block
 145 * returns -1, if block is erased
 146 * returns -2 if error happens
 147 */
 148static int sm_read_lba(struct sm_oob *oob)
 149{
 150        static const uint32_t erased_pattern[4] = {
 151                0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
 152
 153        uint16_t lba_test;
 154        int lba;
 155
 156        /* First test for erased block */
 157        if (!memcmp(oob, erased_pattern, SM_OOB_SIZE))
 158                return -1;
 159
 160        /* Now check is both copies of the LBA differ too much */
 161        lba_test = *(uint16_t *)oob->lba_copy1 ^ *(uint16_t*)oob->lba_copy2;
 162        if (lba_test && !is_power_of_2(lba_test))
 163                return -2;
 164
 165        /* And read it */
 166        lba = sm_get_lba(oob->lba_copy1);
 167
 168        if (lba == -2)
 169                lba = sm_get_lba(oob->lba_copy2);
 170
 171        return lba;
 172}
 173
 174static void sm_write_lba(struct sm_oob *oob, uint16_t lba)
 175{
 176        uint8_t tmp[2];
 177
 178        WARN_ON(lba >= 1000);
 179
 180        tmp[0] = 0x10 | ((lba >> 7) & 0x07);
 181        tmp[1] = (lba << 1) & 0xFF;
 182
 183        if (hweight16(*(uint16_t *)tmp) & 0x01)
 184                tmp[1] |= 1;
 185
 186        oob->lba_copy1[0] = oob->lba_copy2[0] = tmp[0];
 187        oob->lba_copy1[1] = oob->lba_copy2[1] = tmp[1];
 188}
 189
 190
 191/* Make offset from parts */
 192static loff_t sm_mkoffset(struct sm_ftl *ftl, int zone, int block, int boffset)
 193{
 194        WARN_ON(boffset & (SM_SECTOR_SIZE - 1));
 195        WARN_ON(zone < 0 || zone >= ftl->zone_count);
 196        WARN_ON(block >= ftl->zone_size);
 197        WARN_ON(boffset >= ftl->block_size);
 198
 199        if (block == -1)
 200                return -1;
 201
 202        return (zone * SM_MAX_ZONE_SIZE + block) * ftl->block_size + boffset;
 203}
 204
 205/* Breaks offset into parts */
 206static void sm_break_offset(struct sm_ftl *ftl, loff_t loffset,
 207                            int *zone, int *block, int *boffset)
 208{
 209        u64 offset = loffset;
 210        *boffset = do_div(offset, ftl->block_size);
 211        *block = do_div(offset, ftl->max_lba);
 212        *zone = offset >= ftl->zone_count ? -1 : offset;
 213}
 214
 215/* ---------------------- low level IO ------------------------------------- */
 216
 217static int sm_correct_sector(uint8_t *buffer, struct sm_oob *oob)
 218{
 219        uint8_t ecc[3];
 220
 221        __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc,
 222                             IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
 223        if (__nand_correct_data(buffer, ecc, oob->ecc1, SM_SMALL_PAGE,
 224                                IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0)
 225                return -EIO;
 226
 227        buffer += SM_SMALL_PAGE;
 228
 229        __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc,
 230                             IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
 231        if (__nand_correct_data(buffer, ecc, oob->ecc2, SM_SMALL_PAGE,
 232                                IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0)
 233                return -EIO;
 234        return 0;
 235}
 236
 237/* Reads a sector + oob*/
 238static int sm_read_sector(struct sm_ftl *ftl,
 239                          int zone, int block, int boffset,
 240                          uint8_t *buffer, struct sm_oob *oob)
 241{
 242        struct mtd_info *mtd = ftl->trans->mtd;
 243        struct mtd_oob_ops ops;
 244        struct sm_oob tmp_oob;
 245        int ret = -EIO;
 246        int try = 0;
 247
 248        /* FTL can contain -1 entries that are by default filled with bits */
 249        if (block == -1) {
 250                memset(buffer, 0xFF, SM_SECTOR_SIZE);
 251                return 0;
 252        }
 253
 254        /* User might not need the oob, but we do for data verification */
 255        if (!oob)
 256                oob = &tmp_oob;
 257
 258        ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
 259        ops.ooboffs = 0;
 260        ops.ooblen = SM_OOB_SIZE;
 261        ops.oobbuf = (void *)oob;
 262        ops.len = SM_SECTOR_SIZE;
 263        ops.datbuf = buffer;
 264
 265again:
 266        if (try++) {
 267                /* Avoid infinite recursion on CIS reads, sm_recheck_media
 268                        won't help anyway */
 269                if (zone == 0 && block == ftl->cis_block && boffset ==
 270                        ftl->cis_boffset)
 271                        return ret;
 272
 273                /* Test if media is stable */
 274                if (try == 3 || sm_recheck_media(ftl))
 275                        return ret;
 276        }
 277
 278        /* Unfortunately, oob read will _always_ succeed,
 279                despite card removal..... */
 280        ret = mtd_read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
 281
 282        /* Test for unknown errors */
 283        if (ret != 0 && !mtd_is_bitflip_or_eccerr(ret)) {
 284                dbg("read of block %d at zone %d, failed due to error (%d)",
 285                        block, zone, ret);
 286                goto again;
 287        }
 288
 289        /* Do a basic test on the oob, to guard against returned garbage */
 290        if (oob->reserved != 0xFFFFFFFF && !is_power_of_2(~oob->reserved))
 291                goto again;
 292
 293        /* This should never happen, unless there is a bug in the mtd driver */
 294        WARN_ON(ops.oobretlen != SM_OOB_SIZE);
 295        WARN_ON(buffer && ops.retlen != SM_SECTOR_SIZE);
 296
 297        if (!buffer)
 298                return 0;
 299
 300        /* Test if sector marked as bad */
 301        if (!sm_sector_valid(oob)) {
 302                dbg("read of block %d at zone %d, failed because it is marked"
 303                        " as bad" , block, zone);
 304                goto again;
 305        }
 306
 307        /* Test ECC*/
 308        if (mtd_is_eccerr(ret) ||
 309                (ftl->smallpagenand && sm_correct_sector(buffer, oob))) {
 310
 311                dbg("read of block %d at zone %d, failed due to ECC error",
 312                        block, zone);
 313                goto again;
 314        }
 315
 316        return 0;
 317}
 318
 319/* Writes a sector to media */
 320static int sm_write_sector(struct sm_ftl *ftl,
 321                           int zone, int block, int boffset,
 322                           uint8_t *buffer, struct sm_oob *oob)
 323{
 324        struct mtd_oob_ops ops;
 325        struct mtd_info *mtd = ftl->trans->mtd;
 326        int ret;
 327
 328        BUG_ON(ftl->readonly);
 329
 330        if (zone == 0 && (block == ftl->cis_block || block == 0)) {
 331                dbg("attempted to write the CIS!");
 332                return -EIO;
 333        }
 334
 335        if (ftl->unstable)
 336                return -EIO;
 337
 338        ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
 339        ops.len = SM_SECTOR_SIZE;
 340        ops.datbuf = buffer;
 341        ops.ooboffs = 0;
 342        ops.ooblen = SM_OOB_SIZE;
 343        ops.oobbuf = (void *)oob;
 344
 345        ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
 346
 347        /* Now we assume that hardware will catch write bitflip errors */
 348
 349        if (ret) {
 350                dbg("write to block %d at zone %d, failed with error %d",
 351                        block, zone, ret);
 352
 353                sm_recheck_media(ftl);
 354                return ret;
 355        }
 356
 357        /* This should never happen, unless there is a bug in the driver */
 358        WARN_ON(ops.oobretlen != SM_OOB_SIZE);
 359        WARN_ON(buffer && ops.retlen != SM_SECTOR_SIZE);
 360
 361        return 0;
 362}
 363
 364/* ------------------------ block IO ------------------------------------- */
 365
 366/* Write a block using data and lba, and invalid sector bitmap */
 367static int sm_write_block(struct sm_ftl *ftl, uint8_t *buf,
 368                          int zone, int block, int lba,
 369                          unsigned long invalid_bitmap)
 370{
 371        struct sm_oob oob;
 372        int boffset;
 373        int retry = 0;
 374
 375        /* Initialize the oob with requested values */
 376        memset(&oob, 0xFF, SM_OOB_SIZE);
 377        sm_write_lba(&oob, lba);
 378restart:
 379        if (ftl->unstable)
 380                return -EIO;
 381
 382        for (boffset = 0; boffset < ftl->block_size;
 383                                boffset += SM_SECTOR_SIZE) {
 384
 385                oob.data_status = 0xFF;
 386
 387                if (test_bit(boffset / SM_SECTOR_SIZE, &invalid_bitmap)) {
 388
 389                        sm_printk("sector %d of block at LBA %d of zone %d"
 390                                " couldn't be read, marking it as invalid",
 391                                boffset / SM_SECTOR_SIZE, lba, zone);
 392
 393                        oob.data_status = 0;
 394                }
 395
 396                if (ftl->smallpagenand) {
 397                        __nand_calculate_ecc(buf + boffset, SM_SMALL_PAGE,
 398                                        oob.ecc1,
 399                                        IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
 400
 401                        __nand_calculate_ecc(buf + boffset + SM_SMALL_PAGE,
 402                                        SM_SMALL_PAGE, oob.ecc2,
 403                                        IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC));
 404                }
 405                if (!sm_write_sector(ftl, zone, block, boffset,
 406                                                        buf + boffset, &oob))
 407                        continue;
 408
 409                if (!retry) {
 410
 411                        /* If write fails. try to erase the block */
 412                        /* This is safe, because we never write in blocks
 413                                that contain valuable data.
 414                        This is intended to repair block that are marked
 415                        as erased, but that isn't fully erased*/
 416
 417                        if (sm_erase_block(ftl, zone, block, 0))
 418                                return -EIO;
 419
 420                        retry = 1;
 421                        goto restart;
 422                } else {
 423                        sm_mark_block_bad(ftl, zone, block);
 424                        return -EIO;
 425                }
 426        }
 427        return 0;
 428}
 429
 430
 431/* Mark whole block at offset 'offs' as bad. */
 432static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
 433{
 434        struct sm_oob oob;
 435        int boffset;
 436
 437        memset(&oob, 0xFF, SM_OOB_SIZE);
 438        oob.block_status = 0xF0;
 439
 440        if (ftl->unstable)
 441                return;
 442
 443        if (sm_recheck_media(ftl))
 444                return;
 445
 446        sm_printk("marking block %d of zone %d as bad", block, zone);
 447
 448        /* We aren't checking the return value, because we don't care */
 449        /* This also fails on fake xD cards, but I guess these won't expose
 450                any bad blocks till fail completely */
 451        for (boffset = 0; boffset < ftl->block_size; boffset += SM_SECTOR_SIZE)
 452                sm_write_sector(ftl, zone, block, boffset, NULL, &oob);
 453}
 454
 455/*
 456 * Erase a block within a zone
 457 * If erase succeeds, it updates free block fifo, otherwise marks block as bad
 458 */
 459static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
 460                          int put_free)
 461{
 462        struct ftl_zone *zone = &ftl->zones[zone_num];
 463        struct mtd_info *mtd = ftl->trans->mtd;
 464        struct erase_info erase;
 465
 466        erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
 467        erase.len = ftl->block_size;
 468
 469        if (ftl->unstable)
 470                return -EIO;
 471
 472        BUG_ON(ftl->readonly);
 473
 474        if (zone_num == 0 && (block == ftl->cis_block || block == 0)) {
 475                sm_printk("attempted to erase the CIS!");
 476                return -EIO;
 477        }
 478
 479        if (mtd_erase(mtd, &erase)) {
 480                sm_printk("erase of block %d in zone %d failed",
 481                                                        block, zone_num);
 482                goto error;
 483        }
 484
 485        if (put_free)
 486                kfifo_in(&zone->free_sectors,
 487                        (const unsigned char *)&block, sizeof(block));
 488
 489        return 0;
 490error:
 491        sm_mark_block_bad(ftl, zone_num, block);
 492        return -EIO;
 493}
 494
 495/* Thoroughly test that block is valid. */
 496static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
 497{
 498        int boffset;
 499        struct sm_oob oob;
 500        int lbas[] = { -3, 0, 0, 0 };
 501        int i = 0;
 502        int test_lba;
 503
 504
 505        /* First just check that block doesn't look fishy */
 506        /* Only blocks that are valid or are sliced in two parts, are
 507                accepted */
 508        for (boffset = 0; boffset < ftl->block_size;
 509                                        boffset += SM_SECTOR_SIZE) {
 510
 511                /* This shouldn't happen anyway */
 512                if (sm_read_sector(ftl, zone, block, boffset, NULL, &oob))
 513                        return -2;
 514
 515                test_lba = sm_read_lba(&oob);
 516
 517                if (lbas[i] != test_lba)
 518                        lbas[++i] = test_lba;
 519
 520                /* If we found three different LBAs, something is fishy */
 521                if (i == 3)
 522                        return -EIO;
 523        }
 524
 525        /* If the block is sliced (partially erased usually) erase it */
 526        if (i == 2) {
 527                sm_erase_block(ftl, zone, block, 1);
 528                return 1;
 529        }
 530
 531        return 0;
 532}
 533
 534/* ----------------- media scanning --------------------------------- */
 535static const struct chs_entry chs_table[] = {
 536        { 1,    125,  4,  4  },
 537        { 2,    125,  4,  8  },
 538        { 4,    250,  4,  8  },
 539        { 8,    250,  4,  16 },
 540        { 16,   500,  4,  16 },
 541        { 32,   500,  8,  16 },
 542        { 64,   500,  8,  32 },
 543        { 128,  500,  16, 32 },
 544        { 256,  1000, 16, 32 },
 545        { 512,  1015, 32, 63 },
 546        { 1024, 985,  33, 63 },
 547        { 2048, 985,  33, 63 },
 548        { 0 },
 549};
 550
 551
 552static const uint8_t cis_signature[] = {
 553        0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20
 554};
 555/* Find out media parameters.
 556 * This ideally has to be based on nand id, but for now device size is enough */
 557static int sm_get_media_info(struct sm_ftl *ftl, struct mtd_info *mtd)
 558{
 559        int i;
 560        int size_in_megs = mtd->size / (1024 * 1024);
 561
 562        ftl->readonly = mtd->type == MTD_ROM;
 563
 564        /* Manual settings for very old devices */
 565        ftl->zone_count = 1;
 566        ftl->smallpagenand = 0;
 567
 568        switch (size_in_megs) {
 569        case 1:
 570                /* 1 MiB flash/rom SmartMedia card (256 byte pages)*/
 571                ftl->zone_size = 256;
 572                ftl->max_lba = 250;
 573                ftl->block_size = 8 * SM_SECTOR_SIZE;
 574                ftl->smallpagenand = 1;
 575
 576                break;
 577        case 2:
 578                /* 2 MiB flash SmartMedia (256 byte pages)*/
 579                if (mtd->writesize == SM_SMALL_PAGE) {
 580                        ftl->zone_size = 512;
 581                        ftl->max_lba = 500;
 582                        ftl->block_size = 8 * SM_SECTOR_SIZE;
 583                        ftl->smallpagenand = 1;
 584                /* 2 MiB rom SmartMedia */
 585                } else {
 586
 587                        if (!ftl->readonly)
 588                                return -ENODEV;
 589
 590                        ftl->zone_size = 256;
 591                        ftl->max_lba = 250;
 592                        ftl->block_size = 16 * SM_SECTOR_SIZE;
 593                }
 594                break;
 595        case 4:
 596                /* 4 MiB flash/rom SmartMedia device */
 597                ftl->zone_size = 512;
 598                ftl->max_lba = 500;
 599                ftl->block_size = 16 * SM_SECTOR_SIZE;
 600                break;
 601        case 8:
 602                /* 8 MiB flash/rom SmartMedia device */
 603                ftl->zone_size = 1024;
 604                ftl->max_lba = 1000;
 605                ftl->block_size = 16 * SM_SECTOR_SIZE;
 606        }
 607
 608        /* Minimum xD size is 16MiB. Also, all xD cards have standard zone
 609           sizes. SmartMedia cards exist up to 128 MiB and have same layout*/
 610        if (size_in_megs >= 16) {
 611                ftl->zone_count = size_in_megs / 16;
 612                ftl->zone_size = 1024;
 613                ftl->max_lba = 1000;
 614                ftl->block_size = 32 * SM_SECTOR_SIZE;
 615        }
 616
 617        /* Test for proper write,erase and oob sizes */
 618        if (mtd->erasesize > ftl->block_size)
 619                return -ENODEV;
 620
 621        if (mtd->writesize > SM_SECTOR_SIZE)
 622                return -ENODEV;
 623
 624        if (ftl->smallpagenand && mtd->oobsize < SM_SMALL_OOB_SIZE)
 625                return -ENODEV;
 626
 627        if (!ftl->smallpagenand && mtd->oobsize < SM_OOB_SIZE)
 628                return -ENODEV;
 629
 630        /* We use OOB */
 631        if (!mtd_has_oob(mtd))
 632                return -ENODEV;
 633
 634        /* Find geometry information */
 635        for (i = 0 ; i < ARRAY_SIZE(chs_table) ; i++) {
 636                if (chs_table[i].size == size_in_megs) {
 637                        ftl->cylinders = chs_table[i].cyl;
 638                        ftl->heads = chs_table[i].head;
 639                        ftl->sectors = chs_table[i].sec;
 640                        return 0;
 641                }
 642        }
 643
 644        sm_printk("media has unknown size : %dMiB", size_in_megs);
 645        ftl->cylinders = 985;
 646        ftl->heads =  33;
 647        ftl->sectors = 63;
 648        return 0;
 649}
 650
 651/* Validate the CIS */
 652static int sm_read_cis(struct sm_ftl *ftl)
 653{
 654        struct sm_oob oob;
 655
 656        if (sm_read_sector(ftl,
 657                0, ftl->cis_block, ftl->cis_boffset, ftl->cis_buffer, &oob))
 658                        return -EIO;
 659
 660        if (!sm_sector_valid(&oob) || !sm_block_valid(&oob))
 661                return -EIO;
 662
 663        if (!memcmp(ftl->cis_buffer + ftl->cis_page_offset,
 664                        cis_signature, sizeof(cis_signature))) {
 665                return 0;
 666        }
 667
 668        return -EIO;
 669}
 670
 671/* Scan the media for the CIS */
 672static int sm_find_cis(struct sm_ftl *ftl)
 673{
 674        struct sm_oob oob;
 675        int block, boffset;
 676        int block_found = 0;
 677        int cis_found = 0;
 678
 679        /* Search for first valid block */
 680        for (block = 0 ; block < ftl->zone_size - ftl->max_lba ; block++) {
 681
 682                if (sm_read_sector(ftl, 0, block, 0, NULL, &oob))
 683                        continue;
 684
 685                if (!sm_block_valid(&oob))
 686                        continue;
 687                block_found = 1;
 688                break;
 689        }
 690
 691        if (!block_found)
 692                return -EIO;
 693
 694        /* Search for first valid sector in this block */
 695        for (boffset = 0 ; boffset < ftl->block_size;
 696                                                boffset += SM_SECTOR_SIZE) {
 697
 698                if (sm_read_sector(ftl, 0, block, boffset, NULL, &oob))
 699                        continue;
 700
 701                if (!sm_sector_valid(&oob))
 702                        continue;
 703                break;
 704        }
 705
 706        if (boffset == ftl->block_size)
 707                return -EIO;
 708
 709        ftl->cis_block = block;
 710        ftl->cis_boffset = boffset;
 711        ftl->cis_page_offset = 0;
 712
 713        cis_found = !sm_read_cis(ftl);
 714
 715        if (!cis_found) {
 716                ftl->cis_page_offset = SM_SMALL_PAGE;
 717                cis_found = !sm_read_cis(ftl);
 718        }
 719
 720        if (cis_found) {
 721                dbg("CIS block found at offset %x",
 722                        block * ftl->block_size +
 723                                boffset + ftl->cis_page_offset);
 724                return 0;
 725        }
 726        return -EIO;
 727}
 728
 729/* Basic test to determine if underlying mtd device if functional */
 730static int sm_recheck_media(struct sm_ftl *ftl)
 731{
 732        if (sm_read_cis(ftl)) {
 733
 734                if (!ftl->unstable) {
 735                        sm_printk("media unstable, not allowing writes");
 736                        ftl->unstable = 1;
 737                }
 738                return -EIO;
 739        }
 740        return 0;
 741}
 742
 743/* Initialize a FTL zone */
 744static int sm_init_zone(struct sm_ftl *ftl, int zone_num)
 745{
 746        struct ftl_zone *zone = &ftl->zones[zone_num];
 747        struct sm_oob oob;
 748        uint16_t block;
 749        int lba;
 750        int i = 0;
 751        int len;
 752
 753        dbg("initializing zone %d", zone_num);
 754
 755        /* Allocate memory for FTL table */
 756        zone->lba_to_phys_table = kmalloc_array(ftl->max_lba, 2, GFP_KERNEL);
 757
 758        if (!zone->lba_to_phys_table)
 759                return -ENOMEM;
 760        memset(zone->lba_to_phys_table, -1, ftl->max_lba * 2);
 761
 762
 763        /* Allocate memory for free sectors FIFO */
 764        if (kfifo_alloc(&zone->free_sectors, ftl->zone_size * 2, GFP_KERNEL)) {
 765                kfree(zone->lba_to_phys_table);
 766                return -ENOMEM;
 767        }
 768
 769        /* Now scan the zone */
 770        for (block = 0 ; block < ftl->zone_size ; block++) {
 771
 772                /* Skip blocks till the CIS (including) */
 773                if (zone_num == 0 && block <= ftl->cis_block)
 774                        continue;
 775
 776                /* Read the oob of first sector */
 777                if (sm_read_sector(ftl, zone_num, block, 0, NULL, &oob)) {
 778                        kfifo_free(&zone->free_sectors);
 779                        kfree(zone->lba_to_phys_table);
 780                        return -EIO;
 781                }
 782
 783                /* Test to see if block is erased. It is enough to test
 784                        first sector, because erase happens in one shot */
 785                if (sm_block_erased(&oob)) {
 786                        kfifo_in(&zone->free_sectors,
 787                                (unsigned char *)&block, 2);
 788                        continue;
 789                }
 790
 791                /* If block is marked as bad, skip it */
 792                /* This assumes we can trust first sector*/
 793                /* However the way the block valid status is defined, ensures
 794                        very low probability of failure here */
 795                if (!sm_block_valid(&oob)) {
 796                        dbg("PH %04d <-> <marked bad>", block);
 797                        continue;
 798                }
 799
 800
 801                lba = sm_read_lba(&oob);
 802
 803                /* Invalid LBA means that block is damaged. */
 804                /* We can try to erase it, or mark it as bad, but
 805                        lets leave that to recovery application */
 806                if (lba == -2 || lba >= ftl->max_lba) {
 807                        dbg("PH %04d <-> LBA %04d(bad)", block, lba);
 808                        continue;
 809                }
 810
 811
 812                /* If there is no collision,
 813                        just put the sector in the FTL table */
 814                if (zone->lba_to_phys_table[lba] < 0) {
 815                        dbg_verbose("PH %04d <-> LBA %04d", block, lba);
 816                        zone->lba_to_phys_table[lba] = block;
 817                        continue;
 818                }
 819
 820                sm_printk("collision"
 821                        " of LBA %d between blocks %d and %d in zone %d",
 822                        lba, zone->lba_to_phys_table[lba], block, zone_num);
 823
 824                /* Test that this block is valid*/
 825                if (sm_check_block(ftl, zone_num, block))
 826                        continue;
 827
 828                /* Test now the old block */
 829                if (sm_check_block(ftl, zone_num,
 830                                        zone->lba_to_phys_table[lba])) {
 831                        zone->lba_to_phys_table[lba] = block;
 832                        continue;
 833                }
 834
 835                /* If both blocks are valid and share same LBA, it means that
 836                        they hold different versions of same data. It not
 837                        known which is more recent, thus just erase one of them
 838                */
 839                sm_printk("both blocks are valid, erasing the later");
 840                sm_erase_block(ftl, zone_num, block, 1);
 841        }
 842
 843        dbg("zone initialized");
 844        zone->initialized = 1;
 845
 846        /* No free sectors, means that the zone is heavily damaged, write won't
 847                work, but it can still can be (partially) read */
 848        if (!kfifo_len(&zone->free_sectors)) {
 849                sm_printk("no free blocks in zone %d", zone_num);
 850                return 0;
 851        }
 852
 853        /* Randomize first block we write to */
 854        get_random_bytes(&i, 2);
 855        i %= (kfifo_len(&zone->free_sectors) / 2);
 856
 857        while (i--) {
 858                len = kfifo_out(&zone->free_sectors,
 859                                        (unsigned char *)&block, 2);
 860                WARN_ON(len != 2);
 861                kfifo_in(&zone->free_sectors, (const unsigned char *)&block, 2);
 862        }
 863        return 0;
 864}
 865
 866/* Get and automatically initialize an FTL mapping for one zone */
 867static struct ftl_zone *sm_get_zone(struct sm_ftl *ftl, int zone_num)
 868{
 869        struct ftl_zone *zone;
 870        int error;
 871
 872        BUG_ON(zone_num >= ftl->zone_count);
 873        zone = &ftl->zones[zone_num];
 874
 875        if (!zone->initialized) {
 876                error = sm_init_zone(ftl, zone_num);
 877
 878                if (error)
 879                        return ERR_PTR(error);
 880        }
 881        return zone;
 882}
 883
 884
 885/* ----------------- cache handling ------------------------------------------*/
 886
 887/* Initialize the one block cache */
 888static void sm_cache_init(struct sm_ftl *ftl)
 889{
 890        ftl->cache_data_invalid_bitmap = 0xFFFFFFFF;
 891        ftl->cache_clean = 1;
 892        ftl->cache_zone = -1;
 893        ftl->cache_block = -1;
 894        /*memset(ftl->cache_data, 0xAA, ftl->block_size);*/
 895}
 896
 897/* Put sector in one block cache */
 898static void sm_cache_put(struct sm_ftl *ftl, char *buffer, int boffset)
 899{
 900        memcpy(ftl->cache_data + boffset, buffer, SM_SECTOR_SIZE);
 901        clear_bit(boffset / SM_SECTOR_SIZE, &ftl->cache_data_invalid_bitmap);
 902        ftl->cache_clean = 0;
 903}
 904
 905/* Read a sector from the cache */
 906static int sm_cache_get(struct sm_ftl *ftl, char *buffer, int boffset)
 907{
 908        if (test_bit(boffset / SM_SECTOR_SIZE,
 909                &ftl->cache_data_invalid_bitmap))
 910                        return -1;
 911
 912        memcpy(buffer, ftl->cache_data + boffset, SM_SECTOR_SIZE);
 913        return 0;
 914}
 915
 916/* Write the cache to hardware */
 917static int sm_cache_flush(struct sm_ftl *ftl)
 918{
 919        struct ftl_zone *zone;
 920
 921        int sector_num;
 922        uint16_t write_sector;
 923        int zone_num = ftl->cache_zone;
 924        int block_num;
 925
 926        if (ftl->cache_clean)
 927                return 0;
 928
 929        if (ftl->unstable)
 930                return -EIO;
 931
 932        BUG_ON(zone_num < 0);
 933        zone = &ftl->zones[zone_num];
 934        block_num = zone->lba_to_phys_table[ftl->cache_block];
 935
 936
 937        /* Try to read all unread areas of the cache block*/
 938        for_each_set_bit(sector_num, &ftl->cache_data_invalid_bitmap,
 939                ftl->block_size / SM_SECTOR_SIZE) {
 940
 941                if (!sm_read_sector(ftl,
 942                        zone_num, block_num, sector_num * SM_SECTOR_SIZE,
 943                        ftl->cache_data + sector_num * SM_SECTOR_SIZE, NULL))
 944                                clear_bit(sector_num,
 945                                        &ftl->cache_data_invalid_bitmap);
 946        }
 947restart:
 948
 949        if (ftl->unstable)
 950                return -EIO;
 951
 952        /* If there are no spare blocks, */
 953        /* we could still continue by erasing/writing the current block,
 954                but for such worn out media it doesn't worth the trouble,
 955                        and the dangers */
 956        if (kfifo_out(&zone->free_sectors,
 957                                (unsigned char *)&write_sector, 2) != 2) {
 958                dbg("no free sectors for write!");
 959                return -EIO;
 960        }
 961
 962
 963        if (sm_write_block(ftl, ftl->cache_data, zone_num, write_sector,
 964                ftl->cache_block, ftl->cache_data_invalid_bitmap))
 965                        goto restart;
 966
 967        /* Update the FTL table */
 968        zone->lba_to_phys_table[ftl->cache_block] = write_sector;
 969
 970        /* Write succesfull, so erase and free the old block */
 971        if (block_num > 0)
 972                sm_erase_block(ftl, zone_num, block_num, 1);
 973
 974        sm_cache_init(ftl);
 975        return 0;
 976}
 977
 978
 979/* flush timer, runs a second after last write */
 980static void sm_cache_flush_timer(struct timer_list *t)
 981{
 982        struct sm_ftl *ftl = from_timer(ftl, t, timer);
 983        queue_work(cache_flush_workqueue, &ftl->flush_work);
 984}
 985
 986/* cache flush work, kicked by timer */
 987static void sm_cache_flush_work(struct work_struct *work)
 988{
 989        struct sm_ftl *ftl = container_of(work, struct sm_ftl, flush_work);
 990        mutex_lock(&ftl->mutex);
 991        sm_cache_flush(ftl);
 992        mutex_unlock(&ftl->mutex);
 993        return;
 994}
 995
 996/* ---------------- outside interface -------------------------------------- */
 997
 998/* outside interface: read a sector */
 999static int sm_read(struct mtd_blktrans_dev *dev,
1000                   unsigned long sect_no, char *buf)
1001{
1002        struct sm_ftl *ftl = dev->priv;
1003        struct ftl_zone *zone;
1004        int error = 0, in_cache = 0;
1005        int zone_num, block, boffset;
1006
1007        sm_break_offset(ftl, sect_no << 9, &zone_num, &block, &boffset);
1008        mutex_lock(&ftl->mutex);
1009
1010
1011        zone = sm_get_zone(ftl, zone_num);
1012        if (IS_ERR(zone)) {
1013                error = PTR_ERR(zone);
1014                goto unlock;
1015        }
1016
1017        /* Have to look at cache first */
1018        if (ftl->cache_zone == zone_num && ftl->cache_block == block) {
1019                in_cache = 1;
1020                if (!sm_cache_get(ftl, buf, boffset))
1021                        goto unlock;
1022        }
1023
1024        /* Translate the block and return if doesn't exist in the table */
1025        block = zone->lba_to_phys_table[block];
1026
1027        if (block == -1) {
1028                memset(buf, 0xFF, SM_SECTOR_SIZE);
1029                goto unlock;
1030        }
1031
1032        if (sm_read_sector(ftl, zone_num, block, boffset, buf, NULL)) {
1033                error = -EIO;
1034                goto unlock;
1035        }
1036
1037        if (in_cache)
1038                sm_cache_put(ftl, buf, boffset);
1039unlock:
1040        mutex_unlock(&ftl->mutex);
1041        return error;
1042}
1043
1044/* outside interface: write a sector */
1045static int sm_write(struct mtd_blktrans_dev *dev,
1046                                unsigned long sec_no, char *buf)
1047{
1048        struct sm_ftl *ftl = dev->priv;
1049        struct ftl_zone *zone;
1050        int error = 0, zone_num, block, boffset;
1051
1052        BUG_ON(ftl->readonly);
1053        sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset);
1054
1055        /* No need in flush thread running now */
1056        del_timer(&ftl->timer);
1057        mutex_lock(&ftl->mutex);
1058
1059        zone = sm_get_zone(ftl, zone_num);
1060        if (IS_ERR(zone)) {
1061                error = PTR_ERR(zone);
1062                goto unlock;
1063        }
1064
1065        /* If entry is not in cache, flush it */
1066        if (ftl->cache_block != block || ftl->cache_zone != zone_num) {
1067
1068                error = sm_cache_flush(ftl);
1069                if (error)
1070                        goto unlock;
1071
1072                ftl->cache_block = block;
1073                ftl->cache_zone = zone_num;
1074        }
1075
1076        sm_cache_put(ftl, buf, boffset);
1077unlock:
1078        mod_timer(&ftl->timer, jiffies + msecs_to_jiffies(cache_timeout));
1079        mutex_unlock(&ftl->mutex);
1080        return error;
1081}
1082
1083/* outside interface: flush everything */
1084static int sm_flush(struct mtd_blktrans_dev *dev)
1085{
1086        struct sm_ftl *ftl = dev->priv;
1087        int retval;
1088
1089        mutex_lock(&ftl->mutex);
1090        retval =  sm_cache_flush(ftl);
1091        mutex_unlock(&ftl->mutex);
1092        return retval;
1093}
1094
1095/* outside interface: device is released */
1096static void sm_release(struct mtd_blktrans_dev *dev)
1097{
1098        struct sm_ftl *ftl = dev->priv;
1099
1100        mutex_lock(&ftl->mutex);
1101        del_timer_sync(&ftl->timer);
1102        cancel_work_sync(&ftl->flush_work);
1103        sm_cache_flush(ftl);
1104        mutex_unlock(&ftl->mutex);
1105}
1106
1107/* outside interface: get geometry */
1108static int sm_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
1109{
1110        struct sm_ftl *ftl = dev->priv;
1111        geo->heads = ftl->heads;
1112        geo->sectors = ftl->sectors;
1113        geo->cylinders = ftl->cylinders;
1114        return 0;
1115}
1116
1117/* external interface: main initialization function */
1118static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
1119{
1120        struct mtd_blktrans_dev *trans;
1121        struct sm_ftl *ftl;
1122
1123        /* Allocate & initialize our private structure */
1124        ftl = kzalloc(sizeof(struct sm_ftl), GFP_KERNEL);
1125        if (!ftl)
1126                goto error1;
1127
1128
1129        mutex_init(&ftl->mutex);
1130        timer_setup(&ftl->timer, sm_cache_flush_timer, 0);
1131        INIT_WORK(&ftl->flush_work, sm_cache_flush_work);
1132
1133        /* Read media information */
1134        if (sm_get_media_info(ftl, mtd)) {
1135                dbg("found unsupported mtd device, aborting");
1136                goto error2;
1137        }
1138
1139
1140        /* Allocate temporary CIS buffer for read retry support */
1141        ftl->cis_buffer = kzalloc(SM_SECTOR_SIZE, GFP_KERNEL);
1142        if (!ftl->cis_buffer)
1143                goto error2;
1144
1145        /* Allocate zone array, it will be initialized on demand */
1146        ftl->zones = kcalloc(ftl->zone_count, sizeof(struct ftl_zone),
1147                                                                GFP_KERNEL);
1148        if (!ftl->zones)
1149                goto error3;
1150
1151        /* Allocate the cache*/
1152        ftl->cache_data = kzalloc(ftl->block_size, GFP_KERNEL);
1153
1154        if (!ftl->cache_data)
1155                goto error4;
1156
1157        sm_cache_init(ftl);
1158
1159
1160        /* Allocate upper layer structure and initialize it */
1161        trans = kzalloc(sizeof(struct mtd_blktrans_dev), GFP_KERNEL);
1162        if (!trans)
1163                goto error5;
1164
1165        ftl->trans = trans;
1166        trans->priv = ftl;
1167
1168        trans->tr = tr;
1169        trans->mtd = mtd;
1170        trans->devnum = -1;
1171        trans->size = (ftl->block_size * ftl->max_lba * ftl->zone_count) >> 9;
1172        trans->readonly = ftl->readonly;
1173
1174        if (sm_find_cis(ftl)) {
1175                dbg("CIS not found on mtd device, aborting");
1176                goto error6;
1177        }
1178
1179        ftl->disk_attributes = sm_create_sysfs_attributes(ftl);
1180        if (!ftl->disk_attributes)
1181                goto error6;
1182        trans->disk_attributes = ftl->disk_attributes;
1183
1184        sm_printk("Found %d MiB xD/SmartMedia FTL on mtd%d",
1185                (int)(mtd->size / (1024 * 1024)), mtd->index);
1186
1187        dbg("FTL layout:");
1188        dbg("%d zone(s), each consists of %d blocks (+%d spares)",
1189                ftl->zone_count, ftl->max_lba,
1190                ftl->zone_size - ftl->max_lba);
1191        dbg("each block consists of %d bytes",
1192                ftl->block_size);
1193
1194
1195        /* Register device*/
1196        if (add_mtd_blktrans_dev(trans)) {
1197                dbg("error in mtdblktrans layer");
1198                goto error6;
1199        }
1200        return;
1201error6:
1202        kfree(trans);
1203error5:
1204        kfree(ftl->cache_data);
1205error4:
1206        kfree(ftl->zones);
1207error3:
1208        kfree(ftl->cis_buffer);
1209error2:
1210        kfree(ftl);
1211error1:
1212        return;
1213}
1214
1215/* main interface: device {surprise,} removal */
1216static void sm_remove_dev(struct mtd_blktrans_dev *dev)
1217{
1218        struct sm_ftl *ftl = dev->priv;
1219        int i;
1220
1221        del_mtd_blktrans_dev(dev);
1222        ftl->trans = NULL;
1223
1224        for (i = 0 ; i < ftl->zone_count; i++) {
1225
1226                if (!ftl->zones[i].initialized)
1227                        continue;
1228
1229                kfree(ftl->zones[i].lba_to_phys_table);
1230                kfifo_free(&ftl->zones[i].free_sectors);
1231        }
1232
1233        sm_delete_sysfs_attributes(ftl);
1234        kfree(ftl->cis_buffer);
1235        kfree(ftl->zones);
1236        kfree(ftl->cache_data);
1237        kfree(ftl);
1238}
1239
1240static struct mtd_blktrans_ops sm_ftl_ops = {
1241        .name           = "smblk",
1242        .major          = 0,
1243        .part_bits      = SM_FTL_PARTN_BITS,
1244        .blksize        = SM_SECTOR_SIZE,
1245        .getgeo         = sm_getgeo,
1246
1247        .add_mtd        = sm_add_mtd,
1248        .remove_dev     = sm_remove_dev,
1249
1250        .readsect       = sm_read,
1251        .writesect      = sm_write,
1252
1253        .flush          = sm_flush,
1254        .release        = sm_release,
1255
1256        .owner          = THIS_MODULE,
1257};
1258
1259static __init int sm_module_init(void)
1260{
1261        int error = 0;
1262
1263        cache_flush_workqueue = create_freezable_workqueue("smflush");
1264        if (!cache_flush_workqueue)
1265                return -ENOMEM;
1266
1267        error = register_mtd_blktrans(&sm_ftl_ops);
1268        if (error)
1269                destroy_workqueue(cache_flush_workqueue);
1270        return error;
1271
1272}
1273
1274static void __exit sm_module_exit(void)
1275{
1276        destroy_workqueue(cache_flush_workqueue);
1277        deregister_mtd_blktrans(&sm_ftl_ops);
1278}
1279
1280module_init(sm_module_init);
1281module_exit(sm_module_exit);
1282
1283MODULE_LICENSE("GPL");
1284MODULE_AUTHOR("Maxim Levitsky <maximlevitsky@gmail.com>");
1285MODULE_DESCRIPTION("Smartmedia/xD mtd translation layer");
1286