From 22e8c9766a669d49cf3749d397082a5cd93374a9 Mon Sep 17 00:00:00 2001 From: Matias Bjørling Date: Fri, 6 May 2016 20:02:58 +0200 Subject: lightnvm: move block fold outside of get_bb_tbl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The get block table command returns a list of blocks and planes with their associated state. Users, such as gennvm and sysblk, manages all planes as a single virtual block. It was therefore natural to fold the bad block list before it is returned. However, to allow users, which manages on a per-plane block level, to also use the interface, the get_bb_tbl interface is changed to not fold by default and instead let the caller fold if necessary. Reviewed by: Johannes Thumshirn Signed-off-by: Matias Bjørling Signed-off-by: Jens Axboe --- drivers/lightnvm/core.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers/lightnvm/core.c') diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 652b8c7673ee..4cadbe0cd537 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -420,6 +420,41 @@ int nvm_submit_ppa(struct nvm_dev *dev, struct ppa_addr *ppa, int nr_ppas, } EXPORT_SYMBOL(nvm_submit_ppa); +/* + * folds a bad block list from its plane representation to its virtual + * block representation. The fold is done in place and reduced size is + * returned. + * + * If any of the planes status are bad or grown bad block, the virtual block + * is marked bad. If not bad, the first plane state acts as the block state. + */ +int nvm_bb_tbl_fold(struct nvm_dev *dev, u8 *blks, int nr_blks) +{ + int blk, offset, pl, blktype; + + if (nr_blks != dev->blks_per_lun * dev->plane_mode) + return -EINVAL; + + for (blk = 0; blk < dev->blks_per_lun; blk++) { + offset = blk * dev->plane_mode; + blktype = blks[offset]; + + /* Bad blocks on any planes take precedence over other types */ + for (pl = 0; pl < dev->plane_mode; pl++) { + if (blks[offset + pl] & + (NVM_BLK_T_BAD|NVM_BLK_T_GRWN_BAD)) { + blktype = blks[offset + pl]; + break; + } + } + + blks[blk] = blktype; + } + + return dev->blks_per_lun; +} +EXPORT_SYMBOL(nvm_bb_tbl_fold); + static int nvm_init_slc_tbl(struct nvm_dev *dev, struct nvm_id_group *grp) { int i; -- cgit v1.2.3