static int sysblk_get_host_blks(struct nvm_dev *dev, struct ppa_addr ppa, u8 *blks, int nr_blks, struct sysblk_scan *s) { int i, nr_sysblk = 0; nr_blks = nvm_bb_tbl_fold(dev, blks, nr_blks); if (nr_blks < 0) return nr_blks; for (i = 0; i < nr_blks; i++) { if (blks[i] != NVM_BLK_T_HOST) continue; if (s->nr_ppas == MAX_BLKS_PR_SYSBLK * MAX_SYSBLKS) { pr_err("nvm: too many host blks\n"); return -EINVAL; } ppa.g.blk = i; s->ppas[scan_ppa_idx(s->row, nr_sysblk)] = ppa; s->nr_ppas++; nr_sysblk++; } return 0; }
static int sysblk_get_free_blks(struct nvm_dev *dev, struct ppa_addr ppa, u8 *blks, int nr_blks, struct sysblk_scan *s) { struct ppa_addr *sppa; int i, blkid = 0; nr_blks = nvm_bb_tbl_fold(dev, blks, nr_blks); if (nr_blks < 0) return nr_blks; for (i = 0; i < nr_blks; i++) { if (blks[i] == NVM_BLK_T_HOST) return -EEXIST; if (blks[i] != NVM_BLK_T_FREE) continue; sppa = &s->ppas[scan_ppa_idx(s->row, blkid)]; sppa->g.ch = ppa.g.ch; sppa->g.lun = ppa.g.lun; sppa->g.blk = i; s->nr_ppas++; blkid++; pr_debug("nvm: use (%u %u %u) as sysblk\n", sppa->g.ch, sppa->g.lun, sppa->g.blk); if (blkid > MAX_BLKS_PR_SYSBLK - 1) return 0; } pr_err("nvm: sysblk failed get sysblk\n"); return -EINVAL; }
static int pblk_bb_discovery(struct nvm_tgt_dev *dev, struct pblk_lun *rlun) { struct nvm_geo *geo = &dev->geo; struct ppa_addr ppa; u8 *blks; int nr_blks, ret; nr_blks = geo->blks_per_lun * geo->plane_mode; blks = kmalloc(nr_blks, GFP_KERNEL); if (!blks) return -ENOMEM; ppa.ppa = 0; ppa.g.ch = rlun->bppa.g.ch; ppa.g.lun = rlun->bppa.g.lun; ret = nvm_get_tgt_bb_tbl(dev, ppa, blks); if (ret) goto out; nr_blks = nvm_bb_tbl_fold(dev->parent, blks, nr_blks); if (nr_blks < 0) { ret = nr_blks; goto out; } rlun->bb_list = blks; return 0; out: kfree(blks); return ret; }