struct nand_chip *chip = mtd->priv;
        u16 bad;
 
+       if (chip->options & NAND_BB_LAST_PAGE)
+               ofs += mtd->erasesize - mtd->writesize;
+
        page = (int)(ofs >> chip->page_shift) & chip->pagemask;
 
        if (getchip) {
        uint8_t buf[2] = { 0, 0 };
        int block, ret;
 
+       if (chip->options & NAND_BB_LAST_PAGE)
+               ofs += mtd->erasesize - mtd->writesize;
+
        /* Get block number */
        block = (int)(ofs >> chip->bbt_erase_shift);
        if (chip->bbt)
        if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
                chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
 
+       /*
+        * Bad block marker is stored in the last page of each block
+        * on Samsung and Hynix MLC devices
+        */
+       if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                       (*maf_id == NAND_MFR_SAMSUNG ||
+                        *maf_id == NAND_MFR_HYNIX))
+               chip->options |= NAND_BB_LAST_PAGE;
+
        /* Check for AND chips with 4 page planes */
        if (chip->options & NAND_4PAGE_ARRAY)
                chip->erase_cmd = multi_erase_cmd;
 
                from = (loff_t)startblock << (this->bbt_erase_shift - 1);
        }
 
+       if (this->options & NAND_BB_LAST_PAGE)
+               from += mtd->erasesize - (mtd->writesize * len);
+
        for (i = startblock; i < numblocks;) {
                int ret;
 
 
 #define NAND_NO_READRDY                0x00000100
 /* Chip does not allow subpage writes */
 #define NAND_NO_SUBPAGE_WRITE  0x00000200
+/* Chip stores bad block marker on the last page of the eraseblock */
+#define NAND_BB_LAST_PAGE      0x00000400
 
 /* Device is one of 'new' xD cards that expose fake nand command set */
 #define NAND_BROKEN_XD         0x00000400