@@ -3701,6 +3701,39 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
}
}
+static void nand_decode_bbm_fixup(struct nand_chip *chip, u8 id_data[8])
+{
+ struct nand_bbm_page *bbm;
+ int i, j;
+
+ for (i = 0;;i++) {
+ bbm = &nand_bbm_page_fixup[i];
+ if (!bbm->name)
+ /* At the end of the table */
+ break;
+ for (j = 0; j < NAND_MAX_ID_LEN; i++) {
+ if (id_data[i] != bbm->id[i])
+ continue;
+ }
+ /* Now we find the chip */
+ break;
+ }
+
+ if (bbm) {
+ if (bbm->bbm_pages & NAND_BBM_FIRSTPAGE) {
+ chip->bbt_options &= ~NAND_BBT_SCANLASTPAGE;
+ chip->bbt_options &= ~NAND_BBT_SCAN2NDPAGE;
+ }
+ if (bbm->bbm_pages & NAND_BBM_SECONDPAGE) {
+ chip->bbt_options &= ~NAND_BBT_SCANLASTPAGE;
+ chip->bbt_options |= NAND_BBT_SCAN_SCAN2NDPAGE;
+ }
+ if (bbm->bbm_pages & NAND_BBM_LASTPAGE) {
+ chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+ }
+ }
+}
+
/*
* Set the bad block marker/indicator (BBM/BBI) patterns according to some
* heuristic patterns using various detected parameters (e.g., manufacturer,
@@ -3736,6 +3769,8 @@ static void nand_decode_bbm_options(struct mtd_info *mtd,
(mtd->writesize == 2048 &&
maf_id == NAND_MFR_MICRON))
chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+
s00292274@linux-4hy3:linux$ git diff > 1
s00292274@linux-4hy3:linux$ cat 1
@@ -3701,6 +3701,39 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
}
}
+static void nand_decode_bbm_fixup(struct nand_chip *chip, u8 id_data[8])
+{
+ struct nand_bbm_page *bbm;
+ int i, j;
+
+ for (i = 0;;i++) {
+ bbm = &nand_bbm_page_fixup[i];
+ if (!bbm->name)
+ /* At the end of the table */
+ break;
+ for (j = 0; j < NAND_MAX_ID_LEN; i++) {
+ if (id_data[i] != bbm->id[i])
+ continue;
+ }
+ /* Now we find the chip */
+ break;
+ }
+
+ if (bbm) {
+ if (bbm->bbm_pages & NAND_BBM_FIRSTPAGE) {
+ chip->bbt_options &= ~NAND_BBT_SCANLASTPAGE;
+ chip->bbt_options &= ~NAND_BBT_SCAN2NDPAGE;
+ }
+ if (bbm->bbm_pages & NAND_BBM_SECONDPAGE) {
+ chip->bbt_options &= ~NAND_BBT_SCANLASTPAGE;
+ chip->bbt_options |= NAND_BBT_SCAN_SCAN2NDPAGE;
+ }
+ if (bbm->bbm_pages & NAND_BBM_LASTPAGE) {
+ chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+ }
+ }
+}
+
/*
* Set the bad block marker/indicator (BBM/BBI) patterns according to some
* heuristic patterns using various detected parameters (e.g., manufacturer,
@@ -3736,6 +3769,8 @@ static void nand_decode_bbm_options(struct mtd_info *mtd,
(mtd->writesize == 2048 &&
maf_id == NAND_MFR_MICRON))
chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+
+ nand_decode_bbm_fixup(chip, id_data)
}
static inline bool is_full_id_nand(struct nand_flash_dev *type)
@@ -184,8 +184,18 @@ struct nand_manufacturers nand_manuf_ids[] = {
{0x0, "Unknown"}
};
+/* BBM page fixup table */
+struct nand_bbm_page nand_bbm_page_fixup[] = {
+ {"MT29F1G08ABAEAWP:E",
+ {0x2C, 0xF1, 0x80, 0x95, 0x04, 0x00, 0x00, 0x00},
+ NAND_BBM_FIRSTPAGE
+ },
+ {NULL}
+};
+
EXPORT_SYMBOL(nand_manuf_ids);
EXPORT_SYMBOL(nand_flash_ids);
+EXPORT_SYMBOL(nand_bbm_page_fixup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
@@ -829,8 +829,28 @@ struct nand_manufacturers {
char *name;
};
+/**
+ * struct nand_bbm_page - NAND Flash Bad Block Marker Position
+ * @name: NAND chip name
+ * @id: Full device ID
+ * @bbm_page: Which page the BBM locates: NAND_BBM_FIRSTPAGE,
+ * NAND_BBM_SECONDPAGE, NAND_BBM_LASTPAGE
+ */
+struct nand_bbm_page {
+ char *name;
+ union {
+ struct {
+ uint8_t mfr_id;
+ uint8_t dev_id;
+ };
+ uint8_t id[NAND_MAX_ID_LEN];
+ };
+ unsigned int bbm_page;
+};
+
extern struct nand_flash_dev nand_flash_ids[];
extern struct nand_manufacturers nand_manuf_ids[];
+extern struct nand_bbm_page nand_bbm_page_fixup[];
extern int nand_default_bbt(struct mtd_info *mtd);
extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);