Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: Introduce mtd_block_isreserved()

In addition to mtd_block_isbad(), which checks if a block is bad or
reserved, it's needed to check if a block is reserved only (but not
bad). This commit adds an MTD interface for it, in a similar fashion to
mtd_block_isbad().

While here, fix mtd_block_isbad() so the out-of-bounds checking is done
before the callback check.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Pekon Gupta <pekon@ti.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>

authored by

Ezequiel Garcia and committed by
Brian Norris
8471bb73 990a3af0

+57 -3
+13 -3
drivers/mtd/mtdcore.c
··· 1043 1043 } 1044 1044 EXPORT_SYMBOL_GPL(mtd_is_locked); 1045 1045 1046 - int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) 1046 + int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs) 1047 1047 { 1048 - if (!mtd->_block_isbad) 1049 - return 0; 1050 1048 if (ofs < 0 || ofs > mtd->size) 1051 1049 return -EINVAL; 1050 + if (!mtd->_block_isreserved) 1051 + return 0; 1052 + return mtd->_block_isreserved(mtd, ofs); 1053 + } 1054 + EXPORT_SYMBOL_GPL(mtd_block_isreserved); 1055 + 1056 + int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) 1057 + { 1058 + if (ofs < 0 || ofs > mtd->size) 1059 + return -EINVAL; 1060 + if (!mtd->_block_isbad) 1061 + return 0; 1052 1062 return mtd->_block_isbad(mtd, ofs); 1053 1063 } 1054 1064 EXPORT_SYMBOL_GPL(mtd_block_isbad);
+9
drivers/mtd/mtdpart.c
··· 290 290 part->master->_resume(part->master); 291 291 } 292 292 293 + static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs) 294 + { 295 + struct mtd_part *part = PART(mtd); 296 + ofs += part->offset; 297 + return part->master->_block_isreserved(part->master, ofs); 298 + } 299 + 293 300 static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) 294 301 { 295 302 struct mtd_part *part = PART(mtd); ··· 429 422 slave->mtd._unlock = part_unlock; 430 423 if (master->_is_locked) 431 424 slave->mtd._is_locked = part_is_locked; 425 + if (master->_block_isreserved) 426 + slave->mtd._block_isreserved = part_block_isreserved; 432 427 if (master->_block_isbad) 433 428 slave->mtd._block_isbad = part_block_isbad; 434 429 if (master->_block_markbad)
+18
drivers/mtd/nand/nand_base.c
··· 488 488 * nand_block_checkbad - [GENERIC] Check if a block is marked bad 489 489 * @mtd: MTD device structure 490 490 * @ofs: offset from device start 491 + * 492 + * Check if the block is mark as reserved. 493 + */ 494 + static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) 495 + { 496 + struct nand_chip *chip = mtd->priv; 497 + 498 + if (!chip->bbt) 499 + return 0; 500 + /* Return info from the table */ 501 + return nand_isreserved_bbt(mtd, ofs); 502 + } 503 + 504 + /** 505 + * nand_block_checkbad - [GENERIC] Check if a block is marked bad 506 + * @mtd: MTD device structure 507 + * @ofs: offset from device start 491 508 * @getchip: 0, if the chip is already selected 492 509 * @allowbbt: 1, if its allowed to access the bbt area 493 510 * ··· 4128 4111 mtd->_unlock = NULL; 4129 4112 mtd->_suspend = nand_suspend; 4130 4113 mtd->_resume = nand_resume; 4114 + mtd->_block_isreserved = nand_block_isreserved; 4131 4115 mtd->_block_isbad = nand_block_isbad; 4132 4116 mtd->_block_markbad = nand_block_markbad; 4133 4117 mtd->writebufsize = mtd->writesize;
+14
drivers/mtd/nand/nand_bbt.c
··· 1311 1311 } 1312 1312 1313 1313 /** 1314 + * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved 1315 + * @mtd: MTD device structure 1316 + * @offs: offset in the device 1317 + */ 1318 + int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs) 1319 + { 1320 + struct nand_chip *this = mtd->priv; 1321 + int block; 1322 + 1323 + block = (int)(offs >> this->bbt_erase_shift); 1324 + return bbt_get_entry(this, block) == BBT_BLOCK_RESERVED; 1325 + } 1326 + 1327 + /** 1314 1328 * nand_isbad_bbt - [NAND Interface] Check if a block is bad 1315 1329 * @mtd: MTD device structure 1316 1330 * @offs: offset in the device
+2
include/linux/mtd/mtd.h
··· 222 222 int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 223 223 int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 224 224 int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 225 + int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs); 225 226 int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs); 226 227 int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs); 227 228 int (*_suspend) (struct mtd_info *mtd); ··· 303 302 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); 304 303 int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); 305 304 int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len); 305 + int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs); 306 306 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs); 307 307 int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs); 308 308
+1
include/linux/mtd/nand.h
··· 810 810 extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); 811 811 extern int nand_default_bbt(struct mtd_info *mtd); 812 812 extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs); 813 + extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs); 813 814 extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); 814 815 extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, 815 816 int allowbbt);