aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/core.c
diff options
context:
space:
mode:
authorMatias Bjørling <m@bjorling.me>2016-05-06 14:02:58 -0400
committerJens Axboe <axboe@fb.com>2016-05-06 14:51:10 -0400
commit22e8c9766a669d49cf3749d397082a5cd93374a9 (patch)
treec24facba8321c5359bf6f111f2ca892cf894b62a /drivers/lightnvm/core.c
parent4891d120b9cd419f4350b11e1231083745dcdc8b (diff)
lightnvm: move block fold outside of get_bb_tbl()
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 <jthumshirn@suse.de> Signed-off-by: Matias Bjørling <m@bjorling.me> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm/core.c')
-rw-r--r--drivers/lightnvm/core.c35
1 files changed, 35 insertions, 0 deletions
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,
420} 420}
421EXPORT_SYMBOL(nvm_submit_ppa); 421EXPORT_SYMBOL(nvm_submit_ppa);
422 422
423/*
424 * folds a bad block list from its plane representation to its virtual
425 * block representation. The fold is done in place and reduced size is
426 * returned.
427 *
428 * If any of the planes status are bad or grown bad block, the virtual block
429 * is marked bad. If not bad, the first plane state acts as the block state.
430 */
431int nvm_bb_tbl_fold(struct nvm_dev *dev, u8 *blks, int nr_blks)
432{
433 int blk, offset, pl, blktype;
434
435 if (nr_blks != dev->blks_per_lun * dev->plane_mode)
436 return -EINVAL;
437
438 for (blk = 0; blk < dev->blks_per_lun; blk++) {
439 offset = blk * dev->plane_mode;
440 blktype = blks[offset];
441
442 /* Bad blocks on any planes take precedence over other types */
443 for (pl = 0; pl < dev->plane_mode; pl++) {
444 if (blks[offset + pl] &
445 (NVM_BLK_T_BAD|NVM_BLK_T_GRWN_BAD)) {
446 blktype = blks[offset + pl];
447 break;
448 }
449 }
450
451 blks[blk] = blktype;
452 }
453
454 return dev->blks_per_lun;
455}
456EXPORT_SYMBOL(nvm_bb_tbl_fold);
457
423static int nvm_init_slc_tbl(struct nvm_dev *dev, struct nvm_id_group *grp) 458static int nvm_init_slc_tbl(struct nvm_dev *dev, struct nvm_id_group *grp)
424{ 459{
425 int i; 460 int i;