]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/mtd/nand/nand_base.c
fs: jffs2: make jffs2 work zero oobavail
[karo-tx-linux.git] / drivers / mtd / nand / nand_base.c
index d340b2f198c614b72fc68eed945a8c1a662d147c..2d9fe18e58c640e9a364ad065cc58360421dd1c4 100644 (file)
@@ -1741,6 +1741,9 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
        else
                len = mtd->oobsize;
 
+       if (len == 0)
+               return 0;
+
        if (unlikely(ops->ooboffs >= len)) {
                pr_debug("%s: attempt to start read outside oob\n",
                                __func__);
@@ -2409,6 +2412,9 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        else
                len = mtd->oobsize;
 
+       if (len == 0)
+               return 0;
+
        /* Do not allow write past end of page */
        if ((ops->ooboffs + ops->ooblen) > len) {
                pr_debug("%s: attempt to write past end of page\n",
@@ -2912,12 +2918,13 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
        /* get the info we want. */
        ecc = (struct onfi_ext_ecc_info *)cursor;
 
-       if (ecc->codeword_size) {
-               chip->ecc_strength_ds = ecc->ecc_bits;
-               chip->ecc_step_ds = 1 << ecc->codeword_size;
+       if (!ecc->codeword_size) {
+               pr_debug("Invalid codeword size\n");
+               goto ext_out;
        }
 
-       pr_info("ONFI extended param page detected.\n");
+       chip->ecc_strength_ds = ecc->ecc_bits;
+       chip->ecc_step_ds = 1 << ecc->codeword_size;
        ret = 0;
 
 ext_out:
@@ -2935,29 +2942,34 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        int i;
        int val;
 
-       /* ONFI need to be probed in 8 bits mode, and 16 bits should be selected with NAND_BUSWIDTH_AUTO */
-       if (chip->options & NAND_BUSWIDTH_16) {
-               pr_err("Trying ONFI probe in 16 bits mode, aborting !\n");
-               return 0;
-       }
        /* Try ONFI for unknown chip or LP */
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
                chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
                return 0;
 
+       /*
+        * ONFI must be probed in 8-bit mode or with NAND_BUSWIDTH_AUTO, not
+        * with NAND_BUSWIDTH_16
+        */
+       if (chip->options & NAND_BUSWIDTH_16) {
+               pr_err("ONFI cannot be probed in 16-bit mode; aborting\n");
+               return 0;
+       }
+
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
        for (i = 0; i < 3; i++) {
                chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
                                le16_to_cpu(p->crc)) {
-                       pr_info("ONFI param page %d valid\n", i);
                        break;
                }
        }
 
-       if (i == 3)
+       if (i == 3) {
+               pr_err("Could not find valid ONFI parameter page; aborting\n");
                return 0;
+       }
 
        /* Check version */
        val = le16_to_cpu(p->revision);
@@ -2981,11 +2993,23 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        sanitize_string(p->model, sizeof(p->model));
        if (!mtd->name)
                mtd->name = p->model;
+
        mtd->writesize = le32_to_cpu(p->byte_per_page);
-       mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
+
+       /*
+        * pages_per_block and blocks_per_lun may not be a power-of-2 size
+        * (don't ask me who thought of this...). MTD assumes that these
+        * dimensions will be power-of-2, so just truncate the remaining area.
+        */
+       mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
+       mtd->erasesize *= mtd->writesize;
+
        mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
-       chip->chipsize = le32_to_cpu(p->blocks_per_lun);
+
+       /* See erasesize comment */
+       chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
        chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
+       chip->bits_per_cell = p->bits_per_cell;
 
        if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
                *busw = NAND_BUSWIDTH_16;
@@ -3009,10 +3033,11 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 
                /* The Extended Parameter Page is supported since ONFI 2.1. */
                if (nand_flash_detect_ext_param_page(mtd, chip, p))
-                       pr_info("Failed to detect the extended param page.\n");
+                       pr_warn("Failed to detect ONFI extended param page\n");
+       } else {
+               pr_warn("Could not retrieve ONFI ECC requirements\n");
        }
 
-       pr_info("ONFI flash detected\n");
        return 1;
 }
 
@@ -3075,6 +3100,16 @@ static int nand_id_len(u8 *id_data, int arrlen)
        return arrlen;
 }
 
+/* Extract the bits of per cell from the 3rd byte of the extended ID */
+static int nand_get_bits_per_cell(u8 cellinfo)
+{
+       int bits;
+
+       bits = cellinfo & NAND_CI_CELLTYPE_MSK;
+       bits >>= NAND_CI_CELLTYPE_SHIFT;
+       return bits + 1;
+}
+
 /*
  * Many new NAND share similar device ID codes, which represent the size of the
  * chip. The rest of the parameters must be decoded according to generic or
@@ -3085,7 +3120,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 {
        int extid, id_len;
        /* The 3rd id byte holds MLC / multichip data */
-       chip->cellinfo = id_data[2];
+       chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
        /* The 4th id byte is the important one */
        extid = id_data[3];
 
@@ -3101,8 +3136,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
         * ID to decide what to do.
         */
        if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
-                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-                       id_data[5] != 0x00) {
+                       !nand_is_slc(chip) && id_data[5] != 0x00) {
                /* Calc pagesize */
                mtd->writesize = 2048 << (extid & 0x03);
                extid >>= 2;
@@ -3134,7 +3168,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
                        (((extid >> 1) & 0x04) | (extid & 0x03));
                *busw = 0;
        } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
-                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+                       !nand_is_slc(chip)) {
                unsigned int tmp;
 
                /* Calc pagesize */
@@ -3197,7 +3231,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
                 * - ID byte 5, bit[7]:    1 -> BENAND, 0 -> raw SLC
                 */
                if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA &&
-                               !(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                               nand_is_slc(chip) &&
                                (id_data[5] & 0x7) == 0x6 /* 24nm */ &&
                                !(id_data[4] & 0x80) /* !BENAND */) {
                        mtd->oobsize = 32 * mtd->writesize >> 9;
@@ -3222,6 +3256,9 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
        mtd->oobsize = mtd->writesize / 32;
        *busw = type->options & NAND_BUSWIDTH_16;
 
+       /* All legacy ID NAND are small-page, SLC */
+       chip->bits_per_cell = 1;
+
        /*
         * Check for Spansion/AMD ID + repeating 5th, 6th byte since
         * some Spansion chips have erasesize that conflicts with size
@@ -3258,11 +3295,11 @@ static void nand_decode_bbm_options(struct mtd_info *mtd,
         * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
         * AMD/Spansion, and Macronix.  All others scan only the first page.
         */
-       if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+       if (!nand_is_slc(chip) &&
                        (maf_id == NAND_MFR_SAMSUNG ||
                         maf_id == NAND_MFR_HYNIX))
                chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
-       else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+       else if ((nand_is_slc(chip) &&
                                (maf_id == NAND_MFR_SAMSUNG ||
                                 maf_id == NAND_MFR_HYNIX ||
                                 maf_id == NAND_MFR_TOSHIBA ||
@@ -3286,7 +3323,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
                mtd->erasesize = type->erasesize;
                mtd->oobsize = type->oobsize;
 
-               chip->cellinfo = id_data[2];
+               chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
                chip->chipsize = (uint64_t)type->chipsize << 20;
                chip->options |= type->options;
                chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
@@ -3441,11 +3478,13 @@ ident_done:
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
                chip->cmdfunc = nand_command_lp;
 
-       pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
-               " %dMiB, page size: %d, OOB size: %d\n",
+       pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)\n",
                *maf_id, *dev_id, nand_manuf_ids[maf_idx].name,
-               chip->onfi_version ? chip->onfi_params.model : type->name,
-               (int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize);
+               chip->onfi_version ? chip->onfi_params.model : type->name);
+
+       pr_info("NAND device: %dMiB, %s, page size: %d, OOB size: %d\n",
+               (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
+               mtd->writesize, mtd->oobsize);
 
        return type;
 }
@@ -3738,8 +3777,7 @@ int nand_scan_tail(struct mtd_info *mtd)
        chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
 
        /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
-       if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
-           !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+       if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
                switch (chip->ecc.steps) {
                case 2:
                        mtd->subpage_sft = 1;
@@ -3764,7 +3802,7 @@ int nand_scan_tail(struct mtd_info *mtd)
                chip->options |= NAND_SUBPAGE_READ;
 
        /* Fill in remaining MTD driver data */
-       mtd->type = MTD_NANDFLASH;
+       mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
        mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
                                                MTD_CAP_NANDFLASH;
        mtd->_erase = nand_erase;