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

lightnvm: simplify geometry structure

Currently, the device geometry is stored redundantly in the nvm_id and
nvm_geo structures at a device level. Moreover, when instantiating
targets on a specific number of LUNs, these structures are replicated
and manually modified to fit the instance channel and LUN partitioning.

Instead, create a generic geometry around nvm_geo, which can be used by
(i) the underlying device to describe the geometry of the whole device,
and (ii) instances to describe their geometry independently.

Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Javier González and committed by
Jens Axboe
e46f4e48 43d47127

+452 -426
+20 -50
drivers/lightnvm/core.c
··· 155 155 int blun = lun_begin % dev->geo.nr_luns; 156 156 int lunid = 0; 157 157 int lun_balanced = 1; 158 - int prev_nr_luns; 158 + int sec_per_lun, prev_nr_luns; 159 159 int i, j; 160 160 161 161 nr_chnls = (nr_chnls_mod == 0) ? nr_chnls : nr_chnls + 1; ··· 215 215 if (!tgt_dev) 216 216 goto err_ch; 217 217 218 + /* Inherit device geometry from parent */ 218 219 memcpy(&tgt_dev->geo, &dev->geo, sizeof(struct nvm_geo)); 220 + 219 221 /* Target device only owns a portion of the physical device */ 220 222 tgt_dev->geo.nr_chnls = nr_chnls; 221 - tgt_dev->geo.all_luns = nr_luns; 222 223 tgt_dev->geo.nr_luns = (lun_balanced) ? prev_nr_luns : -1; 224 + tgt_dev->geo.all_luns = nr_luns; 225 + tgt_dev->geo.all_chunks = nr_luns * dev->geo.nr_chks; 226 + 223 227 tgt_dev->geo.op = op; 224 - tgt_dev->total_secs = nr_luns * tgt_dev->geo.sec_per_lun; 228 + 229 + sec_per_lun = dev->geo.clba * dev->geo.nr_chks; 230 + tgt_dev->geo.total_secs = nr_luns * sec_per_lun; 231 + 225 232 tgt_dev->q = dev->q; 226 233 tgt_dev->map = dev_map; 227 234 tgt_dev->luns = luns; 228 - memcpy(&tgt_dev->identity, &dev->identity, sizeof(struct nvm_id)); 229 - 230 235 tgt_dev->parent = dev; 231 236 232 237 return tgt_dev; ··· 301 296 static int __nvm_config_extended(struct nvm_dev *dev, 302 297 struct nvm_ioctl_create_extended *e) 303 298 { 304 - struct nvm_geo *geo = &dev->geo; 305 - 306 299 if (e->lun_begin == 0xFFFF && e->lun_end == 0xFFFF) { 307 300 e->lun_begin = 0; 308 301 e->lun_end = dev->geo.all_luns - 1; ··· 314 311 return -EINVAL; 315 312 } 316 313 317 - return nvm_config_check_luns(geo, e->lun_begin, e->lun_end); 314 + return nvm_config_check_luns(&dev->geo, e->lun_begin, e->lun_end); 318 315 } 319 316 320 317 static int nvm_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create) ··· 409 406 tqueue->queuedata = targetdata; 410 407 411 408 blk_queue_max_hw_sectors(tqueue, 412 - (dev->geo.sec_size >> 9) * NVM_MAX_VLBA); 409 + (dev->geo.csecs >> 9) * NVM_MAX_VLBA); 413 410 414 411 set_capacity(tdisk, tt->capacity(targetdata)); 415 412 add_disk(tdisk); ··· 844 841 845 842 static int nvm_core_init(struct nvm_dev *dev) 846 843 { 847 - struct nvm_id *id = &dev->identity; 848 844 struct nvm_geo *geo = &dev->geo; 849 845 int ret; 850 846 851 - memcpy(&geo->ppaf, &id->ppaf, sizeof(struct nvm_addr_format)); 852 - 853 - if (id->mtype != 0) { 854 - pr_err("nvm: memory type not supported\n"); 855 - return -EINVAL; 856 - } 857 - 858 - /* Whole device values */ 859 - geo->nr_chnls = id->num_ch; 860 - geo->nr_luns = id->num_lun; 861 - 862 - /* Generic device geometry values */ 863 - geo->ws_min = id->ws_min; 864 - geo->ws_opt = id->ws_opt; 865 - geo->ws_seq = id->ws_seq; 866 - geo->ws_per_chk = id->ws_per_chk; 867 - geo->nr_chks = id->num_chk; 868 - geo->mccap = id->mccap; 869 - 870 - geo->sec_per_chk = id->clba; 871 - geo->sec_per_lun = geo->sec_per_chk * geo->nr_chks; 872 - geo->all_luns = geo->nr_luns * geo->nr_chnls; 873 - 874 - /* 1.2 spec device geometry values */ 875 - geo->plane_mode = 1 << geo->ws_seq; 876 - geo->nr_planes = geo->ws_opt / geo->ws_min; 877 - geo->sec_per_pg = geo->ws_min; 878 - geo->sec_per_pl = geo->sec_per_pg * geo->nr_planes; 879 - 880 - dev->total_secs = geo->all_luns * geo->sec_per_lun; 881 847 dev->lun_map = kcalloc(BITS_TO_LONGS(geo->all_luns), 882 848 sizeof(unsigned long), GFP_KERNEL); 883 849 if (!dev->lun_map) ··· 885 913 struct nvm_geo *geo = &dev->geo; 886 914 int ret = -EINVAL; 887 915 888 - if (dev->ops->identity(dev, &dev->identity)) { 916 + if (dev->ops->identity(dev)) { 889 917 pr_err("nvm: device could not be identified\n"); 890 918 goto err; 891 919 } 892 920 893 - if (dev->identity.ver_id != 1 && dev->identity.ver_id != 2) { 894 - pr_err("nvm: device ver_id %d not supported by kernel.\n", 895 - dev->identity.ver_id); 896 - goto err; 897 - } 921 + pr_debug("nvm: ver:%u nvm_vendor:%x\n", 922 + geo->ver_id, 923 + geo->vmnt); 898 924 899 925 ret = nvm_core_init(dev); 900 926 if (ret) { ··· 900 930 goto err; 901 931 } 902 932 903 - pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n", 904 - dev->name, geo->sec_per_pg, geo->nr_planes, 905 - geo->ws_per_chk, geo->nr_chks, 906 - geo->all_luns, geo->nr_chnls); 933 + pr_info("nvm: registered %s [%u/%u/%u/%u/%u]\n", 934 + dev->name, geo->ws_min, geo->ws_opt, 935 + geo->nr_chks, geo->all_luns, 936 + geo->nr_chnls); 907 937 return 0; 908 938 err: 909 939 pr_err("nvm: failed to initialize nvm\n");
+8 -8
drivers/lightnvm/pblk-core.c
··· 613 613 memset(&rqd, 0, sizeof(struct nvm_rq)); 614 614 615 615 rq_ppas = pblk_calc_secs(pblk, left_ppas, 0); 616 - rq_len = rq_ppas * geo->sec_size; 616 + rq_len = rq_ppas * geo->csecs; 617 617 618 618 bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len, 619 619 l_mg->emeta_alloc_type, GFP_KERNEL); ··· 722 722 if (bit >= lm->blk_per_line) 723 723 return -1; 724 724 725 - return bit * geo->sec_per_pl; 725 + return bit * geo->ws_opt; 726 726 } 727 727 728 728 static int pblk_line_submit_smeta_io(struct pblk *pblk, struct pblk_line *line, ··· 1034 1034 /* Capture bad block information on line mapping bitmaps */ 1035 1035 while ((bit = find_next_bit(line->blk_bitmap, lm->blk_per_line, 1036 1036 bit + 1)) < lm->blk_per_line) { 1037 - off = bit * geo->sec_per_pl; 1037 + off = bit * geo->ws_opt; 1038 1038 bitmap_shift_left(l_mg->bb_aux, l_mg->bb_template, off, 1039 1039 lm->sec_per_line); 1040 1040 bitmap_or(line->map_bitmap, line->map_bitmap, l_mg->bb_aux, 1041 1041 lm->sec_per_line); 1042 - line->sec_in_line -= geo->sec_per_chk; 1042 + line->sec_in_line -= geo->clba; 1043 1043 } 1044 1044 1045 1045 /* Mark smeta metadata sectors as bad sectors */ 1046 1046 bit = find_first_zero_bit(line->blk_bitmap, lm->blk_per_line); 1047 - off = bit * geo->sec_per_pl; 1047 + off = bit * geo->ws_opt; 1048 1048 bitmap_set(line->map_bitmap, off, lm->smeta_sec); 1049 1049 line->sec_in_line -= lm->smeta_sec; 1050 1050 line->smeta_ssec = off; ··· 1063 1063 emeta_secs = lm->emeta_sec[0]; 1064 1064 off = lm->sec_per_line; 1065 1065 while (emeta_secs) { 1066 - off -= geo->sec_per_pl; 1066 + off -= geo->ws_opt; 1067 1067 if (!test_bit(off, line->invalid_bitmap)) { 1068 - bitmap_set(line->invalid_bitmap, off, geo->sec_per_pl); 1069 - emeta_secs -= geo->sec_per_pl; 1068 + bitmap_set(line->invalid_bitmap, off, geo->ws_opt); 1069 + emeta_secs -= geo->ws_opt; 1070 1070 } 1071 1071 } 1072 1072
+1 -1
drivers/lightnvm/pblk-gc.c
··· 88 88 89 89 up(&gc->gc_sem); 90 90 91 - gc_rq->data = vmalloc(gc_rq->nr_secs * geo->sec_size); 91 + gc_rq->data = vmalloc(gc_rq->nr_secs * geo->csecs); 92 92 if (!gc_rq->data) { 93 93 pr_err("pblk: could not GC line:%d (%d/%d)\n", 94 94 line->id, *line->vsc, gc_rq->nr_secs);
+60 -53
drivers/lightnvm/pblk-init.c
··· 179 179 return -ENOMEM; 180 180 181 181 power_size = get_count_order(nr_entries); 182 - power_seg_sz = get_count_order(geo->sec_size); 182 + power_seg_sz = get_count_order(geo->csecs); 183 183 184 184 return pblk_rb_init(&pblk->rwb, entries, power_size, power_seg_sz); 185 185 } ··· 187 187 /* Minimum pages needed within a lun */ 188 188 #define ADDR_POOL_SIZE 64 189 189 190 - static int pblk_set_ppaf(struct pblk *pblk) 190 + static int pblk_set_addrf_12(struct nvm_geo *geo, struct nvm_addrf_12 *dst) 191 191 { 192 - struct nvm_tgt_dev *dev = pblk->dev; 193 - struct nvm_geo *geo = &dev->geo; 194 - struct nvm_addr_format ppaf = geo->ppaf; 195 - int mod, power_len; 196 - 197 - div_u64_rem(geo->sec_per_chk, pblk->min_write_pgs, &mod); 198 - if (mod) { 199 - pr_err("pblk: bad configuration of sectors/pages\n"); 200 - return -EINVAL; 201 - } 192 + struct nvm_addrf_12 *src = (struct nvm_addrf_12 *)&geo->addrf; 193 + int power_len; 202 194 203 195 /* Re-calculate channel and lun format to adapt to configuration */ 204 196 power_len = get_count_order(geo->nr_chnls); ··· 198 206 pr_err("pblk: supports only power-of-two channel config.\n"); 199 207 return -EINVAL; 200 208 } 201 - ppaf.ch_len = power_len; 209 + dst->ch_len = power_len; 202 210 203 211 power_len = get_count_order(geo->nr_luns); 204 212 if (1 << power_len != geo->nr_luns) { 205 213 pr_err("pblk: supports only power-of-two LUN config.\n"); 206 214 return -EINVAL; 207 215 } 208 - ppaf.lun_len = power_len; 216 + dst->lun_len = power_len; 209 217 210 - pblk->ppaf.sec_offset = 0; 211 - pblk->ppaf.pln_offset = ppaf.sect_len; 212 - pblk->ppaf.ch_offset = pblk->ppaf.pln_offset + ppaf.pln_len; 213 - pblk->ppaf.lun_offset = pblk->ppaf.ch_offset + ppaf.ch_len; 214 - pblk->ppaf.pg_offset = pblk->ppaf.lun_offset + ppaf.lun_len; 215 - pblk->ppaf.blk_offset = pblk->ppaf.pg_offset + ppaf.pg_len; 216 - pblk->ppaf.sec_mask = (1ULL << ppaf.sect_len) - 1; 217 - pblk->ppaf.pln_mask = ((1ULL << ppaf.pln_len) - 1) << 218 - pblk->ppaf.pln_offset; 219 - pblk->ppaf.ch_mask = ((1ULL << ppaf.ch_len) - 1) << 220 - pblk->ppaf.ch_offset; 221 - pblk->ppaf.lun_mask = ((1ULL << ppaf.lun_len) - 1) << 222 - pblk->ppaf.lun_offset; 223 - pblk->ppaf.pg_mask = ((1ULL << ppaf.pg_len) - 1) << 224 - pblk->ppaf.pg_offset; 225 - pblk->ppaf.blk_mask = ((1ULL << ppaf.blk_len) - 1) << 226 - pblk->ppaf.blk_offset; 218 + dst->blk_len = src->blk_len; 219 + dst->pg_len = src->pg_len; 220 + dst->pln_len = src->pln_len; 221 + dst->sect_len = src->sect_len; 227 222 228 - pblk->ppaf_bitsize = pblk->ppaf.blk_offset + ppaf.blk_len; 223 + dst->sect_offset = 0; 224 + dst->pln_offset = dst->sect_len; 225 + dst->ch_offset = dst->pln_offset + dst->pln_len; 226 + dst->lun_offset = dst->ch_offset + dst->ch_len; 227 + dst->pg_offset = dst->lun_offset + dst->lun_len; 228 + dst->blk_offset = dst->pg_offset + dst->pg_len; 229 + 230 + dst->sec_mask = ((1ULL << dst->sect_len) - 1) << dst->sect_offset; 231 + dst->pln_mask = ((1ULL << dst->pln_len) - 1) << dst->pln_offset; 232 + dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset; 233 + dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset; 234 + dst->pg_mask = ((1ULL << dst->pg_len) - 1) << dst->pg_offset; 235 + dst->blk_mask = ((1ULL << dst->blk_len) - 1) << dst->blk_offset; 236 + 237 + return dst->blk_offset + src->blk_len; 238 + } 239 + 240 + static int pblk_set_ppaf(struct pblk *pblk) 241 + { 242 + struct nvm_tgt_dev *dev = pblk->dev; 243 + struct nvm_geo *geo = &dev->geo; 244 + int mod; 245 + 246 + div_u64_rem(geo->clba, pblk->min_write_pgs, &mod); 247 + if (mod) { 248 + pr_err("pblk: bad configuration of sectors/pages\n"); 249 + return -EINVAL; 250 + } 251 + 252 + pblk->ppaf_bitsize = pblk_set_addrf_12(geo, (void *)&pblk->ppaf); 229 253 230 254 return 0; 231 255 } ··· 311 303 atomic64_set(&pblk->nr_flush, 0); 312 304 pblk->nr_flush_rst = 0; 313 305 314 - pblk->pgs_in_buffer = NVM_MEM_PAGE_WRITE * geo->sec_per_pg * 315 - geo->nr_planes * geo->all_luns; 306 + pblk->pgs_in_buffer = geo->mw_cunits * geo->all_luns; 316 307 317 - pblk->min_write_pgs = geo->sec_per_pl * (geo->sec_size / PAGE_SIZE); 308 + pblk->min_write_pgs = geo->ws_opt * (geo->csecs / PAGE_SIZE); 318 309 max_write_ppas = pblk->min_write_pgs * geo->all_luns; 319 310 pblk->max_write_pgs = min_t(int, max_write_ppas, NVM_MAX_VLBA); 320 311 pblk_set_sec_per_write(pblk, pblk->min_write_pgs); ··· 590 583 /* Round to sector size so that lba_list starts on its own sector */ 591 584 lm->emeta_sec[1] = DIV_ROUND_UP( 592 585 sizeof(struct line_emeta) + lm->blk_bitmap_len + 593 - sizeof(struct wa_counters), geo->sec_size); 594 - lm->emeta_len[1] = lm->emeta_sec[1] * geo->sec_size; 586 + sizeof(struct wa_counters), geo->csecs); 587 + lm->emeta_len[1] = lm->emeta_sec[1] * geo->csecs; 595 588 596 589 /* Round to sector size so that vsc_list starts on its own sector */ 597 590 lm->dsec_per_line = lm->sec_per_line - lm->emeta_sec[0]; 598 591 lm->emeta_sec[2] = DIV_ROUND_UP(lm->dsec_per_line * sizeof(u64), 599 - geo->sec_size); 600 - lm->emeta_len[2] = lm->emeta_sec[2] * geo->sec_size; 592 + geo->csecs); 593 + lm->emeta_len[2] = lm->emeta_sec[2] * geo->csecs; 601 594 602 595 lm->emeta_sec[3] = DIV_ROUND_UP(l_mg->nr_lines * sizeof(u32), 603 - geo->sec_size); 604 - lm->emeta_len[3] = lm->emeta_sec[3] * geo->sec_size; 596 + geo->csecs); 597 + lm->emeta_len[3] = lm->emeta_sec[3] * geo->csecs; 605 598 606 599 lm->vsc_list_len = l_mg->nr_lines * sizeof(u32); 607 600 ··· 632 625 * on user capacity consider only provisioned blocks 633 626 */ 634 627 pblk->rl.total_blocks = nr_free_blks; 635 - pblk->rl.nr_secs = nr_free_blks * geo->sec_per_chk; 628 + pblk->rl.nr_secs = nr_free_blks * geo->clba; 636 629 637 630 /* Consider sectors used for metadata */ 638 631 sec_meta = (lm->smeta_sec + lm->emeta_sec[0]) * l_mg->nr_free_lines; 639 - blk_meta = DIV_ROUND_UP(sec_meta, geo->sec_per_chk); 632 + blk_meta = DIV_ROUND_UP(sec_meta, geo->clba); 640 633 641 - pblk->capacity = (provisioned - blk_meta) * geo->sec_per_chk; 634 + pblk->capacity = (provisioned - blk_meta) * geo->clba; 642 635 643 636 atomic_set(&pblk->rl.free_blocks, nr_free_blks); 644 637 atomic_set(&pblk->rl.free_user_blocks, nr_free_blks); ··· 790 783 unsigned int smeta_len, emeta_len; 791 784 int i; 792 785 793 - lm->sec_per_line = geo->sec_per_chk * geo->all_luns; 786 + lm->sec_per_line = geo->clba * geo->all_luns; 794 787 lm->blk_per_line = geo->all_luns; 795 788 lm->blk_bitmap_len = BITS_TO_LONGS(geo->all_luns) * sizeof(long); 796 789 lm->sec_bitmap_len = BITS_TO_LONGS(lm->sec_per_line) * sizeof(long); ··· 804 797 */ 805 798 i = 1; 806 799 add_smeta_page: 807 - lm->smeta_sec = i * geo->sec_per_pl; 808 - lm->smeta_len = lm->smeta_sec * geo->sec_size; 800 + lm->smeta_sec = i * geo->ws_opt; 801 + lm->smeta_len = lm->smeta_sec * geo->csecs; 809 802 810 803 smeta_len = sizeof(struct line_smeta) + lm->lun_bitmap_len; 811 804 if (smeta_len > lm->smeta_len) { ··· 818 811 */ 819 812 i = 1; 820 813 add_emeta_page: 821 - lm->emeta_sec[0] = i * geo->sec_per_pl; 822 - lm->emeta_len[0] = lm->emeta_sec[0] * geo->sec_size; 814 + lm->emeta_sec[0] = i * geo->ws_opt; 815 + lm->emeta_len[0] = lm->emeta_sec[0] * geo->csecs; 823 816 824 817 emeta_len = calc_emeta_len(pblk); 825 818 if (emeta_len > lm->emeta_len[0]) { ··· 832 825 lm->min_blk_line = 1; 833 826 if (geo->all_luns > 1) 834 827 lm->min_blk_line += DIV_ROUND_UP(lm->smeta_sec + 835 - lm->emeta_sec[0], geo->sec_per_chk); 828 + lm->emeta_sec[0], geo->clba); 836 829 837 830 if (lm->min_blk_line > lm->blk_per_line) { 838 831 pr_err("pblk: config. not supported. Min. LUN in line:%d\n", ··· 1016 1009 struct pblk *pblk; 1017 1010 int ret; 1018 1011 1019 - if (dev->identity.dom & NVM_RSP_L2P) { 1012 + if (dev->geo.dom & NVM_RSP_L2P) { 1020 1013 pr_err("pblk: host-side L2P table not supported. (%x)\n", 1021 - dev->identity.dom); 1014 + dev->geo.dom); 1022 1015 return ERR_PTR(-EINVAL); 1023 1016 } 1024 1017 ··· 1100 1093 1101 1094 blk_queue_write_cache(tqueue, true, false); 1102 1095 1103 - tqueue->limits.discard_granularity = geo->sec_per_chk * geo->sec_size; 1096 + tqueue->limits.discard_granularity = geo->clba * geo->csecs; 1104 1097 tqueue->limits.discard_alignment = 0; 1105 1098 blk_queue_max_discard_sectors(tqueue, UINT_MAX >> 9); 1106 1099 blk_queue_flag_set(QUEUE_FLAG_DISCARD, tqueue);
+1 -1
drivers/lightnvm/pblk-read.c
··· 563 563 if (!(gc_rq->secs_to_gc)) 564 564 goto out; 565 565 566 - data_len = (gc_rq->secs_to_gc) * geo->sec_size; 566 + data_len = (gc_rq->secs_to_gc) * geo->csecs; 567 567 bio = pblk_bio_map_addr(pblk, gc_rq->data, gc_rq->secs_to_gc, data_len, 568 568 PBLK_VMALLOC_META, GFP_KERNEL); 569 569 if (IS_ERR(bio)) {
+7 -7
drivers/lightnvm/pblk-recovery.c
··· 184 184 int nr_bb = bitmap_weight(line->blk_bitmap, lm->blk_per_line); 185 185 186 186 return lm->sec_per_line - lm->smeta_sec - lm->emeta_sec[0] - 187 - nr_bb * geo->sec_per_chk; 187 + nr_bb * geo->clba; 188 188 } 189 189 190 190 struct pblk_recov_alloc { ··· 232 232 rq_ppas = pblk_calc_secs(pblk, left_ppas, 0); 233 233 if (!rq_ppas) 234 234 rq_ppas = pblk->min_write_pgs; 235 - rq_len = rq_ppas * geo->sec_size; 235 + rq_len = rq_ppas * geo->csecs; 236 236 237 237 bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL); 238 238 if (IS_ERR(bio)) ··· 351 351 if (!pad_rq) 352 352 return -ENOMEM; 353 353 354 - data = vzalloc(pblk->max_write_pgs * geo->sec_size); 354 + data = vzalloc(pblk->max_write_pgs * geo->csecs); 355 355 if (!data) { 356 356 ret = -ENOMEM; 357 357 goto free_rq; ··· 368 368 goto fail_free_pad; 369 369 } 370 370 371 - rq_len = rq_ppas * geo->sec_size; 371 + rq_len = rq_ppas * geo->csecs; 372 372 373 373 meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, &dma_meta_list); 374 374 if (!meta_list) { ··· 509 509 rq_ppas = pblk_calc_secs(pblk, left_ppas, 0); 510 510 if (!rq_ppas) 511 511 rq_ppas = pblk->min_write_pgs; 512 - rq_len = rq_ppas * geo->sec_size; 512 + rq_len = rq_ppas * geo->csecs; 513 513 514 514 bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL); 515 515 if (IS_ERR(bio)) ··· 640 640 rq_ppas = pblk_calc_secs(pblk, left_ppas, 0); 641 641 if (!rq_ppas) 642 642 rq_ppas = pblk->min_write_pgs; 643 - rq_len = rq_ppas * geo->sec_size; 643 + rq_len = rq_ppas * geo->csecs; 644 644 645 645 bio = bio_map_kern(dev->q, data, rq_len, GFP_KERNEL); 646 646 if (IS_ERR(bio)) ··· 745 745 ppa_list = (void *)(meta_list) + pblk_dma_meta_size; 746 746 dma_ppa_list = dma_meta_list + pblk_dma_meta_size; 747 747 748 - data = kcalloc(pblk->max_write_pgs, geo->sec_size, GFP_KERNEL); 748 + data = kcalloc(pblk->max_write_pgs, geo->csecs, GFP_KERNEL); 749 749 if (!data) { 750 750 ret = -ENOMEM; 751 751 goto free_meta_list;
+1 -1
drivers/lightnvm/pblk-rl.c
··· 200 200 201 201 /* Consider sectors used for metadata */ 202 202 sec_meta = (lm->smeta_sec + lm->emeta_sec[0]) * l_mg->nr_free_lines; 203 - blk_meta = DIV_ROUND_UP(sec_meta, geo->sec_per_chk); 203 + blk_meta = DIV_ROUND_UP(sec_meta, geo->clba); 204 204 205 205 rl->high = pblk->op_blks - blk_meta - lm->blk_per_line; 206 206 rl->high_pw = get_count_order(rl->high);
+20 -15
drivers/lightnvm/pblk-sysfs.c
··· 113 113 { 114 114 struct nvm_tgt_dev *dev = pblk->dev; 115 115 struct nvm_geo *geo = &dev->geo; 116 + struct nvm_addrf_12 *ppaf; 117 + struct nvm_addrf_12 *geo_ppaf; 116 118 ssize_t sz = 0; 117 119 118 - sz = snprintf(page, PAGE_SIZE - sz, 120 + ppaf = (struct nvm_addrf_12 *)&pblk->ppaf; 121 + geo_ppaf = (struct nvm_addrf_12 *)&geo->addrf; 122 + 123 + sz = snprintf(page, PAGE_SIZE, 119 124 "g:(b:%d)blk:%d/%d,pg:%d/%d,lun:%d/%d,ch:%d/%d,pl:%d/%d,sec:%d/%d\n", 120 - pblk->ppaf_bitsize, 121 - pblk->ppaf.blk_offset, geo->ppaf.blk_len, 122 - pblk->ppaf.pg_offset, geo->ppaf.pg_len, 123 - pblk->ppaf.lun_offset, geo->ppaf.lun_len, 124 - pblk->ppaf.ch_offset, geo->ppaf.ch_len, 125 - pblk->ppaf.pln_offset, geo->ppaf.pln_len, 126 - pblk->ppaf.sec_offset, geo->ppaf.sect_len); 125 + pblk->ppaf_bitsize, 126 + ppaf->blk_offset, ppaf->blk_len, 127 + ppaf->pg_offset, ppaf->pg_len, 128 + ppaf->lun_offset, ppaf->lun_len, 129 + ppaf->ch_offset, ppaf->ch_len, 130 + ppaf->pln_offset, ppaf->pln_len, 131 + ppaf->sect_offset, ppaf->sect_len); 127 132 128 133 sz += snprintf(page + sz, PAGE_SIZE - sz, 129 134 "d:blk:%d/%d,pg:%d/%d,lun:%d/%d,ch:%d/%d,pl:%d/%d,sec:%d/%d\n", 130 - geo->ppaf.blk_offset, geo->ppaf.blk_len, 131 - geo->ppaf.pg_offset, geo->ppaf.pg_len, 132 - geo->ppaf.lun_offset, geo->ppaf.lun_len, 133 - geo->ppaf.ch_offset, geo->ppaf.ch_len, 134 - geo->ppaf.pln_offset, geo->ppaf.pln_len, 135 - geo->ppaf.sect_offset, geo->ppaf.sect_len); 135 + geo_ppaf->blk_offset, geo_ppaf->blk_len, 136 + geo_ppaf->pg_offset, geo_ppaf->pg_len, 137 + geo_ppaf->lun_offset, geo_ppaf->lun_len, 138 + geo_ppaf->ch_offset, geo_ppaf->ch_len, 139 + geo_ppaf->pln_offset, geo_ppaf->pln_len, 140 + geo_ppaf->sect_offset, geo_ppaf->sect_len); 136 141 137 142 return sz; 138 143 } ··· 293 288 "blk_line:%d, sec_line:%d, sec_blk:%d\n", 294 289 lm->blk_per_line, 295 290 lm->sec_per_line, 296 - geo->sec_per_chk); 291 + geo->clba); 297 292 298 293 return sz; 299 294 }
+1 -1
drivers/lightnvm/pblk-write.c
··· 333 333 m_ctx = nvm_rq_to_pdu(rqd); 334 334 m_ctx->private = meta_line; 335 335 336 - rq_len = rq_ppas * geo->sec_size; 336 + rq_len = rq_ppas * geo->csecs; 337 337 data = ((void *)emeta->buf) + emeta->mem; 338 338 339 339 bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
+33 -50
drivers/lightnvm/pblk.h
··· 551 551 unsigned int meta_distance; /* Distance between data and metadata */ 552 552 }; 553 553 554 - struct pblk_addr_format { 555 - u64 ch_mask; 556 - u64 lun_mask; 557 - u64 pln_mask; 558 - u64 blk_mask; 559 - u64 pg_mask; 560 - u64 sec_mask; 561 - u8 ch_offset; 562 - u8 lun_offset; 563 - u8 pln_offset; 564 - u8 blk_offset; 565 - u8 pg_offset; 566 - u8 sec_offset; 567 - }; 568 - 569 554 enum { 570 555 PBLK_STATE_RUNNING = 0, 571 556 PBLK_STATE_STOPPING = 1, ··· 570 585 struct pblk_line_mgmt l_mg; /* Line management */ 571 586 struct pblk_line_meta lm; /* Line metadata */ 572 587 588 + struct nvm_addrf ppaf; 573 589 int ppaf_bitsize; 574 - struct pblk_addr_format ppaf; 575 590 576 591 struct pblk_rb rwb; 577 592 ··· 926 941 return le32_to_cpu(*line->vsc); 927 942 } 928 943 929 - #define NVM_MEM_PAGE_WRITE (8) 930 - 931 944 static inline int pblk_pad_distance(struct pblk *pblk) 932 945 { 933 946 struct nvm_tgt_dev *dev = pblk->dev; 934 947 struct nvm_geo *geo = &dev->geo; 935 948 936 - return NVM_MEM_PAGE_WRITE * geo->all_luns * geo->sec_per_pl; 949 + return geo->mw_cunits * geo->all_luns * geo->ws_opt; 937 950 } 938 951 939 952 static inline int pblk_ppa_to_line(struct ppa_addr p) ··· 947 964 static inline struct ppa_addr addr_to_gen_ppa(struct pblk *pblk, u64 paddr, 948 965 u64 line_id) 949 966 { 967 + struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf; 950 968 struct ppa_addr ppa; 951 969 952 970 ppa.ppa = 0; 953 971 ppa.g.blk = line_id; 954 - ppa.g.pg = (paddr & pblk->ppaf.pg_mask) >> pblk->ppaf.pg_offset; 955 - ppa.g.lun = (paddr & pblk->ppaf.lun_mask) >> pblk->ppaf.lun_offset; 956 - ppa.g.ch = (paddr & pblk->ppaf.ch_mask) >> pblk->ppaf.ch_offset; 957 - ppa.g.pl = (paddr & pblk->ppaf.pln_mask) >> pblk->ppaf.pln_offset; 958 - ppa.g.sec = (paddr & pblk->ppaf.sec_mask) >> pblk->ppaf.sec_offset; 972 + ppa.g.pg = (paddr & ppaf->pg_mask) >> ppaf->pg_offset; 973 + ppa.g.lun = (paddr & ppaf->lun_mask) >> ppaf->lun_offset; 974 + ppa.g.ch = (paddr & ppaf->ch_mask) >> ppaf->ch_offset; 975 + ppa.g.pl = (paddr & ppaf->pln_mask) >> ppaf->pln_offset; 976 + ppa.g.sec = (paddr & ppaf->sec_mask) >> ppaf->sect_offset; 959 977 960 978 return ppa; 961 979 } ··· 964 980 static inline u64 pblk_dev_ppa_to_line_addr(struct pblk *pblk, 965 981 struct ppa_addr p) 966 982 { 983 + struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf; 967 984 u64 paddr; 968 985 969 - paddr = (u64)p.g.pg << pblk->ppaf.pg_offset; 970 - paddr |= (u64)p.g.lun << pblk->ppaf.lun_offset; 971 - paddr |= (u64)p.g.ch << pblk->ppaf.ch_offset; 972 - paddr |= (u64)p.g.pl << pblk->ppaf.pln_offset; 973 - paddr |= (u64)p.g.sec << pblk->ppaf.sec_offset; 986 + paddr = (u64)p.g.ch << ppaf->ch_offset; 987 + paddr |= (u64)p.g.lun << ppaf->lun_offset; 988 + paddr |= (u64)p.g.pg << ppaf->pg_offset; 989 + paddr |= (u64)p.g.pl << ppaf->pln_offset; 990 + paddr |= (u64)p.g.sec << ppaf->sect_offset; 974 991 975 992 return paddr; 976 993 } ··· 988 1003 ppa64.c.line = ppa32 & ((~0U) >> 1); 989 1004 ppa64.c.is_cached = 1; 990 1005 } else { 991 - ppa64.g.blk = (ppa32 & pblk->ppaf.blk_mask) >> 992 - pblk->ppaf.blk_offset; 993 - ppa64.g.pg = (ppa32 & pblk->ppaf.pg_mask) >> 994 - pblk->ppaf.pg_offset; 995 - ppa64.g.lun = (ppa32 & pblk->ppaf.lun_mask) >> 996 - pblk->ppaf.lun_offset; 997 - ppa64.g.ch = (ppa32 & pblk->ppaf.ch_mask) >> 998 - pblk->ppaf.ch_offset; 999 - ppa64.g.pl = (ppa32 & pblk->ppaf.pln_mask) >> 1000 - pblk->ppaf.pln_offset; 1001 - ppa64.g.sec = (ppa32 & pblk->ppaf.sec_mask) >> 1002 - pblk->ppaf.sec_offset; 1006 + struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf; 1007 + 1008 + ppa64.g.ch = (ppa32 & ppaf->ch_mask) >> ppaf->ch_offset; 1009 + ppa64.g.lun = (ppa32 & ppaf->lun_mask) >> ppaf->lun_offset; 1010 + ppa64.g.blk = (ppa32 & ppaf->blk_mask) >> ppaf->blk_offset; 1011 + ppa64.g.pg = (ppa32 & ppaf->pg_mask) >> ppaf->pg_offset; 1012 + ppa64.g.pl = (ppa32 & ppaf->pln_mask) >> ppaf->pln_offset; 1013 + ppa64.g.sec = (ppa32 & ppaf->sec_mask) >> ppaf->sect_offset; 1003 1014 } 1004 1015 1005 1016 return ppa64; ··· 1011 1030 ppa32 |= ppa64.c.line; 1012 1031 ppa32 |= 1U << 31; 1013 1032 } else { 1014 - ppa32 |= ppa64.g.blk << pblk->ppaf.blk_offset; 1015 - ppa32 |= ppa64.g.pg << pblk->ppaf.pg_offset; 1016 - ppa32 |= ppa64.g.lun << pblk->ppaf.lun_offset; 1017 - ppa32 |= ppa64.g.ch << pblk->ppaf.ch_offset; 1018 - ppa32 |= ppa64.g.pl << pblk->ppaf.pln_offset; 1019 - ppa32 |= ppa64.g.sec << pblk->ppaf.sec_offset; 1033 + struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&pblk->ppaf; 1034 + 1035 + ppa32 |= ppa64.g.ch << ppaf->ch_offset; 1036 + ppa32 |= ppa64.g.lun << ppaf->lun_offset; 1037 + ppa32 |= ppa64.g.blk << ppaf->blk_offset; 1038 + ppa32 |= ppa64.g.pg << ppaf->pg_offset; 1039 + ppa32 |= ppa64.g.pl << ppaf->pln_offset; 1040 + ppa32 |= ppa64.g.sec << ppaf->sect_offset; 1020 1041 } 1021 1042 1022 1043 return ppa32; ··· 1212 1229 if (!ppa->c.is_cached && 1213 1230 ppa->g.ch < geo->nr_chnls && 1214 1231 ppa->g.lun < geo->nr_luns && 1215 - ppa->g.pl < geo->nr_planes && 1232 + ppa->g.pl < geo->num_pln && 1216 1233 ppa->g.blk < geo->nr_chks && 1217 - ppa->g.pg < geo->ws_per_chk && 1218 - ppa->g.sec < geo->sec_per_pg) 1234 + ppa->g.pg < geo->num_pg && 1235 + ppa->g.sec < geo->ws_min) 1219 1236 continue; 1220 1237 1221 1238 print_ppa(ppa, "boundary", i);
+202 -141
drivers/nvme/host/lightnvm.c
··· 152 152 __u8 blk_len; 153 153 __u8 pg_offset; 154 154 __u8 pg_len; 155 - __u8 sect_offset; 156 - __u8 sect_len; 155 + __u8 sec_offset; 156 + __u8 sec_len; 157 157 __u8 res[4]; 158 158 } __packed; 159 159 ··· 254 254 BUILD_BUG_ON(sizeof(struct nvme_nvm_id20) != NVME_IDENTIFY_DATA_SIZE); 255 255 } 256 256 257 - static int init_grp(struct nvm_id *nvm_id, struct nvme_nvm_id12 *id12) 257 + static void nvme_nvm_set_addr_12(struct nvm_addrf_12 *dst, 258 + struct nvme_nvm_id12_addrf *src) 259 + { 260 + dst->ch_len = src->ch_len; 261 + dst->lun_len = src->lun_len; 262 + dst->blk_len = src->blk_len; 263 + dst->pg_len = src->pg_len; 264 + dst->pln_len = src->pln_len; 265 + dst->sect_len = src->sec_len; 266 + 267 + dst->ch_offset = src->ch_offset; 268 + dst->lun_offset = src->lun_offset; 269 + dst->blk_offset = src->blk_offset; 270 + dst->pg_offset = src->pg_offset; 271 + dst->pln_offset = src->pln_offset; 272 + dst->sect_offset = src->sec_offset; 273 + 274 + dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset; 275 + dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset; 276 + dst->blk_mask = ((1ULL << dst->blk_len) - 1) << dst->blk_offset; 277 + dst->pg_mask = ((1ULL << dst->pg_len) - 1) << dst->pg_offset; 278 + dst->pln_mask = ((1ULL << dst->pln_len) - 1) << dst->pln_offset; 279 + dst->sec_mask = ((1ULL << dst->sect_len) - 1) << dst->sect_offset; 280 + } 281 + 282 + static int nvme_nvm_setup_12(struct nvme_nvm_id12 *id, 283 + struct nvm_geo *geo) 258 284 { 259 285 struct nvme_nvm_id12_grp *src; 260 286 int sec_per_pg, sec_per_pl, pg_per_blk; 261 287 262 - if (id12->cgrps != 1) 288 + if (id->cgrps != 1) 263 289 return -EINVAL; 264 290 265 - src = &id12->grp; 291 + src = &id->grp; 266 292 267 - nvm_id->mtype = src->mtype; 268 - nvm_id->fmtype = src->fmtype; 269 - 270 - nvm_id->num_ch = src->num_ch; 271 - nvm_id->num_lun = src->num_lun; 272 - 273 - nvm_id->num_chk = le16_to_cpu(src->num_chk); 274 - nvm_id->csecs = le16_to_cpu(src->csecs); 275 - nvm_id->sos = le16_to_cpu(src->sos); 276 - 277 - pg_per_blk = le16_to_cpu(src->num_pg); 278 - sec_per_pg = le16_to_cpu(src->fpg_sz) / nvm_id->csecs; 279 - sec_per_pl = sec_per_pg * src->num_pln; 280 - nvm_id->clba = sec_per_pl * pg_per_blk; 281 - nvm_id->ws_per_chk = pg_per_blk; 282 - 283 - nvm_id->mpos = le32_to_cpu(src->mpos); 284 - nvm_id->cpar = le16_to_cpu(src->cpar); 285 - nvm_id->mccap = le32_to_cpu(src->mccap); 286 - 287 - nvm_id->ws_opt = nvm_id->ws_min = sec_per_pg; 288 - nvm_id->ws_seq = NVM_IO_SNGL_ACCESS; 289 - 290 - if (nvm_id->mpos & 0x020202) { 291 - nvm_id->ws_seq = NVM_IO_DUAL_ACCESS; 292 - nvm_id->ws_opt <<= 1; 293 - } else if (nvm_id->mpos & 0x040404) { 294 - nvm_id->ws_seq = NVM_IO_QUAD_ACCESS; 295 - nvm_id->ws_opt <<= 2; 293 + if (src->mtype != 0) { 294 + pr_err("nvm: memory type not supported\n"); 295 + return -EINVAL; 296 296 } 297 297 298 - nvm_id->trdt = le32_to_cpu(src->trdt); 299 - nvm_id->trdm = le32_to_cpu(src->trdm); 300 - nvm_id->tprt = le32_to_cpu(src->tprt); 301 - nvm_id->tprm = le32_to_cpu(src->tprm); 302 - nvm_id->tbet = le32_to_cpu(src->tbet); 303 - nvm_id->tbem = le32_to_cpu(src->tbem); 298 + geo->ver_id = id->ver_id; 299 + 300 + geo->nr_chnls = src->num_ch; 301 + geo->nr_luns = src->num_lun; 302 + geo->all_luns = geo->nr_chnls * geo->nr_luns; 303 + 304 + geo->nr_chks = le16_to_cpu(src->num_chk); 305 + 306 + geo->csecs = le16_to_cpu(src->csecs); 307 + geo->sos = le16_to_cpu(src->sos); 308 + 309 + pg_per_blk = le16_to_cpu(src->num_pg); 310 + sec_per_pg = le16_to_cpu(src->fpg_sz) / geo->csecs; 311 + sec_per_pl = sec_per_pg * src->num_pln; 312 + geo->clba = sec_per_pl * pg_per_blk; 313 + 314 + geo->all_chunks = geo->all_luns * geo->nr_chks; 315 + geo->total_secs = geo->clba * geo->all_chunks; 316 + 317 + geo->ws_min = sec_per_pg; 318 + geo->ws_opt = sec_per_pg; 319 + geo->mw_cunits = geo->ws_opt << 3; /* default to MLC safe values */ 320 + 321 + geo->mccap = le32_to_cpu(src->mccap); 322 + 323 + geo->trdt = le32_to_cpu(src->trdt); 324 + geo->trdm = le32_to_cpu(src->trdm); 325 + geo->tprt = le32_to_cpu(src->tprt); 326 + geo->tprm = le32_to_cpu(src->tprm); 327 + geo->tbet = le32_to_cpu(src->tbet); 328 + geo->tbem = le32_to_cpu(src->tbem); 304 329 305 330 /* 1.2 compatibility */ 306 - nvm_id->num_pln = src->num_pln; 307 - nvm_id->num_pg = le16_to_cpu(src->num_pg); 308 - nvm_id->fpg_sz = le16_to_cpu(src->fpg_sz); 331 + geo->vmnt = id->vmnt; 332 + geo->cap = le32_to_cpu(id->cap); 333 + geo->dom = le32_to_cpu(id->dom); 334 + 335 + geo->mtype = src->mtype; 336 + geo->fmtype = src->fmtype; 337 + 338 + geo->cpar = le16_to_cpu(src->cpar); 339 + geo->mpos = le32_to_cpu(src->mpos); 340 + 341 + geo->plane_mode = NVM_PLANE_SINGLE; 342 + 343 + if (geo->mpos & 0x020202) { 344 + geo->plane_mode = NVM_PLANE_DOUBLE; 345 + geo->ws_opt <<= 1; 346 + } else if (geo->mpos & 0x040404) { 347 + geo->plane_mode = NVM_PLANE_QUAD; 348 + geo->ws_opt <<= 2; 349 + } 350 + 351 + geo->num_pln = src->num_pln; 352 + geo->num_pg = le16_to_cpu(src->num_pg); 353 + geo->fpg_sz = le16_to_cpu(src->fpg_sz); 354 + 355 + nvme_nvm_set_addr_12((struct nvm_addrf_12 *)&geo->addrf, &id->ppaf); 309 356 310 357 return 0; 311 358 } 312 359 313 - static int nvme_nvm_setup_12(struct nvm_dev *nvmdev, struct nvm_id *nvm_id, 314 - struct nvme_nvm_id12 *id) 360 + static void nvme_nvm_set_addr_20(struct nvm_addrf *dst, 361 + struct nvme_nvm_id20_addrf *src) 315 362 { 316 - nvm_id->ver_id = id->ver_id; 317 - nvm_id->vmnt = id->vmnt; 318 - nvm_id->cap = le32_to_cpu(id->cap); 319 - nvm_id->dom = le32_to_cpu(id->dom); 320 - memcpy(&nvm_id->ppaf, &id->ppaf, 321 - sizeof(struct nvm_addr_format)); 363 + dst->ch_len = src->grp_len; 364 + dst->lun_len = src->pu_len; 365 + dst->chk_len = src->chk_len; 366 + dst->sec_len = src->lba_len; 322 367 323 - return init_grp(nvm_id, id); 368 + dst->sec_offset = 0; 369 + dst->chk_offset = dst->sec_len; 370 + dst->lun_offset = dst->chk_offset + dst->chk_len; 371 + dst->ch_offset = dst->lun_offset + dst->lun_len; 372 + 373 + dst->ch_mask = ((1ULL << dst->ch_len) - 1) << dst->ch_offset; 374 + dst->lun_mask = ((1ULL << dst->lun_len) - 1) << dst->lun_offset; 375 + dst->chk_mask = ((1ULL << dst->chk_len) - 1) << dst->chk_offset; 376 + dst->sec_mask = ((1ULL << dst->sec_len) - 1) << dst->sec_offset; 324 377 } 325 378 326 - static int nvme_nvm_setup_20(struct nvm_dev *nvmdev, struct nvm_id *nvm_id, 327 - struct nvme_nvm_id20 *id) 379 + static int nvme_nvm_setup_20(struct nvme_nvm_id20 *id, 380 + struct nvm_geo *geo) 328 381 { 329 - nvm_id->ver_id = id->mjr; 382 + geo->ver_id = id->mjr; 330 383 331 - nvm_id->num_ch = le16_to_cpu(id->num_grp); 332 - nvm_id->num_lun = le16_to_cpu(id->num_pu); 333 - nvm_id->num_chk = le32_to_cpu(id->num_chk); 334 - nvm_id->clba = le32_to_cpu(id->clba); 384 + geo->nr_chnls = le16_to_cpu(id->num_grp); 385 + geo->nr_luns = le16_to_cpu(id->num_pu); 386 + geo->all_luns = geo->nr_chnls * geo->nr_luns; 335 387 336 - nvm_id->ws_min = le32_to_cpu(id->ws_min); 337 - nvm_id->ws_opt = le32_to_cpu(id->ws_opt); 338 - nvm_id->mw_cunits = le32_to_cpu(id->mw_cunits); 388 + geo->nr_chks = le32_to_cpu(id->num_chk); 389 + geo->clba = le32_to_cpu(id->clba); 339 390 340 - nvm_id->trdt = le32_to_cpu(id->trdt); 341 - nvm_id->trdm = le32_to_cpu(id->trdm); 342 - nvm_id->tprt = le32_to_cpu(id->twrt); 343 - nvm_id->tprm = le32_to_cpu(id->twrm); 344 - nvm_id->tbet = le32_to_cpu(id->tcrst); 345 - nvm_id->tbem = le32_to_cpu(id->tcrsm); 391 + geo->all_chunks = geo->all_luns * geo->nr_chks; 392 + geo->total_secs = geo->clba * geo->all_chunks; 346 393 347 - /* calculated values */ 348 - nvm_id->ws_per_chk = nvm_id->clba / nvm_id->ws_min; 394 + geo->ws_min = le32_to_cpu(id->ws_min); 395 + geo->ws_opt = le32_to_cpu(id->ws_opt); 396 + geo->mw_cunits = le32_to_cpu(id->mw_cunits); 349 397 350 - /* 1.2 compatibility */ 351 - nvm_id->ws_seq = NVM_IO_SNGL_ACCESS; 398 + geo->trdt = le32_to_cpu(id->trdt); 399 + geo->trdm = le32_to_cpu(id->trdm); 400 + geo->tprt = le32_to_cpu(id->twrt); 401 + geo->tprm = le32_to_cpu(id->twrm); 402 + geo->tbet = le32_to_cpu(id->tcrst); 403 + geo->tbem = le32_to_cpu(id->tcrsm); 404 + 405 + nvme_nvm_set_addr_20(&geo->addrf, &id->lbaf); 352 406 353 407 return 0; 354 408 } 355 409 356 - static int nvme_nvm_identity(struct nvm_dev *nvmdev, struct nvm_id *nvm_id) 410 + static int nvme_nvm_identity(struct nvm_dev *nvmdev) 357 411 { 358 412 struct nvme_ns *ns = nvmdev->q->queuedata; 359 413 struct nvme_nvm_id12 *id; ··· 434 380 */ 435 381 switch (id->ver_id) { 436 382 case 1: 437 - ret = nvme_nvm_setup_12(nvmdev, nvm_id, id); 383 + ret = nvme_nvm_setup_12(id, &nvmdev->geo); 438 384 break; 439 385 case 2: 440 - ret = nvme_nvm_setup_20(nvmdev, nvm_id, 441 - (struct nvme_nvm_id20 *)id); 386 + ret = nvme_nvm_setup_20((struct nvme_nvm_id20 *)id, 387 + &nvmdev->geo); 442 388 break; 443 389 default: 444 - dev_err(ns->ctrl->device, 445 - "OCSSD revision not supported (%d)\n", 446 - nvm_id->ver_id); 390 + dev_err(ns->ctrl->device, "OCSSD revision not supported (%d)\n", 391 + id->ver_id); 447 392 ret = -EINVAL; 448 393 } 394 + 449 395 out: 450 396 kfree(id); 451 397 return ret; ··· 460 406 struct nvme_ctrl *ctrl = ns->ctrl; 461 407 struct nvme_nvm_command c = {}; 462 408 struct nvme_nvm_bb_tbl *bb_tbl; 463 - int nr_blks = geo->nr_chks * geo->plane_mode; 409 + int nr_blks = geo->nr_chks * geo->num_pln; 464 410 int tblsz = sizeof(struct nvme_nvm_bb_tbl) + nr_blks; 465 411 int ret = 0; 466 412 ··· 501 447 goto out; 502 448 } 503 449 504 - memcpy(blks, bb_tbl->blk, geo->nr_chks * geo->plane_mode); 450 + memcpy(blks, bb_tbl->blk, geo->nr_chks * geo->num_pln); 505 451 out: 506 452 kfree(bb_tbl); 507 453 return ret; ··· 869 815 void nvme_nvm_update_nvm_info(struct nvme_ns *ns) 870 816 { 871 817 struct nvm_dev *ndev = ns->ndev; 818 + struct nvm_geo *geo = &ndev->geo; 872 819 873 - ndev->identity.csecs = ndev->geo.sec_size = 1 << ns->lba_shift; 874 - ndev->identity.sos = ndev->geo.oob_size = ns->ms; 820 + geo->csecs = 1 << ns->lba_shift; 821 + geo->sos = ns->ms; 875 822 } 876 823 877 824 int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node) ··· 905 850 { 906 851 struct nvme_ns *ns = nvme_get_ns_from_dev(dev); 907 852 struct nvm_dev *ndev = ns->ndev; 908 - struct nvm_id *id; 853 + struct nvm_geo *geo = &ndev->geo; 909 854 struct attribute *attr; 910 855 911 856 if (!ndev) 912 857 return 0; 913 858 914 - id = &ndev->identity; 915 859 attr = &dattr->attr; 916 860 917 861 if (strcmp(attr->name, "version") == 0) { 918 - return scnprintf(page, PAGE_SIZE, "%u\n", id->ver_id); 862 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->ver_id); 919 863 } else if (strcmp(attr->name, "capabilities") == 0) { 920 - return scnprintf(page, PAGE_SIZE, "%u\n", id->cap); 864 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->cap); 921 865 } else if (strcmp(attr->name, "read_typ") == 0) { 922 - return scnprintf(page, PAGE_SIZE, "%u\n", id->trdt); 866 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->trdt); 923 867 } else if (strcmp(attr->name, "read_max") == 0) { 924 - return scnprintf(page, PAGE_SIZE, "%u\n", id->trdm); 868 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->trdm); 925 869 } else { 926 870 return scnprintf(page, 927 871 PAGE_SIZE, ··· 929 875 } 930 876 } 931 877 878 + static ssize_t nvm_dev_attr_show_ppaf(struct nvm_addrf_12 *ppaf, char *page) 879 + { 880 + return scnprintf(page, PAGE_SIZE, 881 + "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 882 + ppaf->ch_offset, ppaf->ch_len, 883 + ppaf->lun_offset, ppaf->lun_len, 884 + ppaf->pln_offset, ppaf->pln_len, 885 + ppaf->blk_offset, ppaf->blk_len, 886 + ppaf->pg_offset, ppaf->pg_len, 887 + ppaf->sect_offset, ppaf->sect_len); 888 + } 889 + 932 890 static ssize_t nvm_dev_attr_show_12(struct device *dev, 933 891 struct device_attribute *dattr, char *page) 934 892 { 935 893 struct nvme_ns *ns = nvme_get_ns_from_dev(dev); 936 894 struct nvm_dev *ndev = ns->ndev; 937 - struct nvm_id *id; 895 + struct nvm_geo *geo = &ndev->geo; 938 896 struct attribute *attr; 939 897 940 898 if (!ndev) 941 899 return 0; 942 900 943 - id = &ndev->identity; 944 901 attr = &dattr->attr; 945 902 946 903 if (strcmp(attr->name, "vendor_opcode") == 0) { 947 - return scnprintf(page, PAGE_SIZE, "%u\n", id->vmnt); 904 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->vmnt); 948 905 } else if (strcmp(attr->name, "device_mode") == 0) { 949 - return scnprintf(page, PAGE_SIZE, "%u\n", id->dom); 906 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->dom); 950 907 /* kept for compatibility */ 951 908 } else if (strcmp(attr->name, "media_manager") == 0) { 952 909 return scnprintf(page, PAGE_SIZE, "%s\n", "gennvm"); 953 910 } else if (strcmp(attr->name, "ppa_format") == 0) { 954 - return scnprintf(page, PAGE_SIZE, 955 - "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 956 - id->ppaf.ch_offset, id->ppaf.ch_len, 957 - id->ppaf.lun_offset, id->ppaf.lun_len, 958 - id->ppaf.pln_offset, id->ppaf.pln_len, 959 - id->ppaf.blk_offset, id->ppaf.blk_len, 960 - id->ppaf.pg_offset, id->ppaf.pg_len, 961 - id->ppaf.sect_offset, id->ppaf.sect_len); 911 + return nvm_dev_attr_show_ppaf((void *)&geo->addrf, page); 962 912 } else if (strcmp(attr->name, "media_type") == 0) { /* u8 */ 963 - return scnprintf(page, PAGE_SIZE, "%u\n", id->mtype); 913 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->mtype); 964 914 } else if (strcmp(attr->name, "flash_media_type") == 0) { 965 - return scnprintf(page, PAGE_SIZE, "%u\n", id->fmtype); 915 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->fmtype); 966 916 } else if (strcmp(attr->name, "num_channels") == 0) { 967 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_ch); 917 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->nr_chnls); 968 918 } else if (strcmp(attr->name, "num_luns") == 0) { 969 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_lun); 919 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->nr_luns); 970 920 } else if (strcmp(attr->name, "num_planes") == 0) { 971 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_pln); 921 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_pln); 972 922 } else if (strcmp(attr->name, "num_blocks") == 0) { /* u16 */ 973 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_chk); 923 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->nr_chks); 974 924 } else if (strcmp(attr->name, "num_pages") == 0) { 975 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_pg); 925 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->num_pg); 976 926 } else if (strcmp(attr->name, "page_size") == 0) { 977 - return scnprintf(page, PAGE_SIZE, "%u\n", id->fpg_sz); 927 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->fpg_sz); 978 928 } else if (strcmp(attr->name, "hw_sector_size") == 0) { 979 - return scnprintf(page, PAGE_SIZE, "%u\n", id->csecs); 929 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->csecs); 980 930 } else if (strcmp(attr->name, "oob_sector_size") == 0) {/* u32 */ 981 - return scnprintf(page, PAGE_SIZE, "%u\n", id->sos); 931 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->sos); 982 932 } else if (strcmp(attr->name, "prog_typ") == 0) { 983 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tprt); 933 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprt); 984 934 } else if (strcmp(attr->name, "prog_max") == 0) { 985 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tprm); 935 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprm); 986 936 } else if (strcmp(attr->name, "erase_typ") == 0) { 987 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tbet); 937 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbet); 988 938 } else if (strcmp(attr->name, "erase_max") == 0) { 989 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tbem); 939 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbem); 990 940 } else if (strcmp(attr->name, "multiplane_modes") == 0) { 991 - return scnprintf(page, PAGE_SIZE, "0x%08x\n", id->mpos); 941 + return scnprintf(page, PAGE_SIZE, "0x%08x\n", geo->mpos); 992 942 } else if (strcmp(attr->name, "media_capabilities") == 0) { 993 - return scnprintf(page, PAGE_SIZE, "0x%08x\n", id->mccap); 943 + return scnprintf(page, PAGE_SIZE, "0x%08x\n", geo->mccap); 994 944 } else if (strcmp(attr->name, "max_phys_secs") == 0) { 995 945 return scnprintf(page, PAGE_SIZE, "%u\n", NVM_MAX_VLBA); 996 946 } else { 997 - return scnprintf(page, 998 - PAGE_SIZE, 999 - "Unhandled attr(%s) in `nvm_dev_attr_show_12`\n", 1000 - attr->name); 947 + return scnprintf(page, PAGE_SIZE, 948 + "Unhandled attr(%s) in `nvm_dev_attr_show_12`\n", 949 + attr->name); 1001 950 } 1002 951 } 1003 952 ··· 1009 952 { 1010 953 struct nvme_ns *ns = nvme_get_ns_from_dev(dev); 1011 954 struct nvm_dev *ndev = ns->ndev; 1012 - struct nvm_id *id; 955 + struct nvm_geo *geo = &ndev->geo; 1013 956 struct attribute *attr; 1014 957 1015 958 if (!ndev) 1016 959 return 0; 1017 960 1018 - id = &ndev->identity; 1019 961 attr = &dattr->attr; 1020 962 1021 963 if (strcmp(attr->name, "groups") == 0) { 1022 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_ch); 964 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->nr_chnls); 1023 965 } else if (strcmp(attr->name, "punits") == 0) { 1024 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_lun); 966 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->nr_luns); 1025 967 } else if (strcmp(attr->name, "chunks") == 0) { 1026 - return scnprintf(page, PAGE_SIZE, "%u\n", id->num_chk); 968 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->nr_chks); 1027 969 } else if (strcmp(attr->name, "clba") == 0) { 1028 - return scnprintf(page, PAGE_SIZE, "%u\n", id->clba); 970 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->clba); 1029 971 } else if (strcmp(attr->name, "ws_min") == 0) { 1030 - return scnprintf(page, PAGE_SIZE, "%u\n", id->ws_min); 972 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->ws_min); 1031 973 } else if (strcmp(attr->name, "ws_opt") == 0) { 1032 - return scnprintf(page, PAGE_SIZE, "%u\n", id->ws_opt); 974 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->ws_opt); 1033 975 } else if (strcmp(attr->name, "mw_cunits") == 0) { 1034 - return scnprintf(page, PAGE_SIZE, "%u\n", id->mw_cunits); 976 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->mw_cunits); 1035 977 } else if (strcmp(attr->name, "write_typ") == 0) { 1036 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tprt); 978 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprt); 1037 979 } else if (strcmp(attr->name, "write_max") == 0) { 1038 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tprm); 980 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tprm); 1039 981 } else if (strcmp(attr->name, "reset_typ") == 0) { 1040 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tbet); 982 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbet); 1041 983 } else if (strcmp(attr->name, "reset_max") == 0) { 1042 - return scnprintf(page, PAGE_SIZE, "%u\n", id->tbem); 984 + return scnprintf(page, PAGE_SIZE, "%u\n", geo->tbem); 1043 985 } else { 1044 - return scnprintf(page, 1045 - PAGE_SIZE, 1046 - "Unhandled attr(%s) in `nvm_dev_attr_show_20`\n", 1047 - attr->name); 986 + return scnprintf(page, PAGE_SIZE, 987 + "Unhandled attr(%s) in `nvm_dev_attr_show_20`\n", 988 + attr->name); 1048 989 } 1049 990 } 1050 991 ··· 1161 1106 1162 1107 int nvme_nvm_register_sysfs(struct nvme_ns *ns) 1163 1108 { 1164 - if (!ns->ndev) 1109 + struct nvm_dev *ndev = ns->ndev; 1110 + struct nvm_geo *geo = &ndev->geo; 1111 + 1112 + if (!ndev) 1165 1113 return -EINVAL; 1166 1114 1167 - switch (ns->ndev->identity.ver_id) { 1115 + switch (geo->ver_id) { 1168 1116 case 1: 1169 1117 return sysfs_create_group(&disk_to_dev(ns->disk)->kobj, 1170 1118 &nvm_dev_attr_group_12); ··· 1181 1123 1182 1124 void nvme_nvm_unregister_sysfs(struct nvme_ns *ns) 1183 1125 { 1184 - switch (ns->ndev->identity.ver_id) { 1126 + struct nvm_dev *ndev = ns->ndev; 1127 + struct nvm_geo *geo = &ndev->geo; 1128 + 1129 + switch (geo->ver_id) { 1185 1130 case 1: 1186 1131 sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, 1187 1132 &nvm_dev_attr_group_12);
+98 -98
include/linux/lightnvm.h
··· 50 50 struct nvm_dev; 51 51 struct nvm_tgt_dev; 52 52 53 - typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *); 53 + typedef int (nvm_id_fn)(struct nvm_dev *); 54 54 typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *); 55 55 typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int); 56 56 typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *); ··· 152 152 struct nvm_id_lp_mlc mlc; 153 153 }; 154 154 155 - struct nvm_addr_format { 156 - u8 ch_offset; 155 + struct nvm_addrf_12 { 157 156 u8 ch_len; 158 - u8 lun_offset; 159 157 u8 lun_len; 160 - u8 pln_offset; 161 - u8 pln_len; 162 - u8 blk_offset; 163 158 u8 blk_len; 164 - u8 pg_offset; 165 159 u8 pg_len; 166 - u8 sect_offset; 160 + u8 pln_len; 167 161 u8 sect_len; 162 + 163 + u8 ch_offset; 164 + u8 lun_offset; 165 + u8 blk_offset; 166 + u8 pg_offset; 167 + u8 pln_offset; 168 + u8 sect_offset; 169 + 170 + u64 ch_mask; 171 + u64 lun_mask; 172 + u64 blk_mask; 173 + u64 pg_mask; 174 + u64 pln_mask; 175 + u64 sec_mask; 168 176 }; 169 177 170 - struct nvm_id { 171 - u8 ver_id; 172 - u8 vmnt; 173 - u32 cap; 174 - u32 dom; 178 + struct nvm_addrf { 179 + u8 ch_len; 180 + u8 lun_len; 181 + u8 chk_len; 182 + u8 sec_len; 183 + u8 rsv_len[2]; 175 184 176 - struct nvm_addr_format ppaf; 185 + u8 ch_offset; 186 + u8 lun_offset; 187 + u8 chk_offset; 188 + u8 sec_offset; 189 + u8 rsv_off[2]; 177 190 178 - u8 num_ch; 179 - u8 num_lun; 180 - u16 num_chk; 181 - u16 clba; 182 - u16 csecs; 183 - u16 sos; 184 - 185 - u32 ws_min; 186 - u32 ws_opt; 187 - u32 mw_cunits; 188 - 189 - u32 trdt; 190 - u32 trdm; 191 - u32 tprt; 192 - u32 tprm; 193 - u32 tbet; 194 - u32 tbem; 195 - u32 mpos; 196 - u32 mccap; 197 - u16 cpar; 198 - 199 - /* calculated values */ 200 - u16 ws_seq; 201 - u16 ws_per_chk; 202 - 203 - /* 1.2 compatibility */ 204 - u8 mtype; 205 - u8 fmtype; 206 - 207 - u8 num_pln; 208 - u16 num_pg; 209 - u16 fpg_sz; 210 - } __packed; 191 + u64 ch_mask; 192 + u64 lun_mask; 193 + u64 chk_mask; 194 + u64 sec_mask; 195 + u64 rsv_mask[2]; 196 + }; 211 197 212 198 struct nvm_target { 213 199 struct list_head list; ··· 260 274 NVM_BLK_ST_BAD = 0x8, /* Bad block */ 261 275 }; 262 276 263 - 264 - /* Device generic information */ 277 + /* Instance geometry */ 265 278 struct nvm_geo { 266 - /* generic geometry */ 279 + /* device reported version */ 280 + u8 ver_id; 281 + 282 + /* instance specific geometry */ 267 283 int nr_chnls; 268 - int all_luns; /* across channels */ 269 - int nr_luns; /* per channel */ 270 - int nr_chks; /* per lun */ 284 + int nr_luns; /* per channel */ 271 285 272 - int sec_size; 273 - int oob_size; 274 - int mccap; 286 + /* calculated values */ 287 + int all_luns; /* across channels */ 288 + int all_chunks; /* across channels */ 275 289 276 - int sec_per_chk; 277 - int sec_per_lun; 290 + int op; /* over-provision in instance */ 278 291 279 - int ws_min; 280 - int ws_opt; 281 - int ws_seq; 282 - int ws_per_chk; 292 + sector_t total_secs; /* across channels */ 283 293 284 - int op; 294 + /* chunk geometry */ 295 + u32 nr_chks; /* chunks per lun */ 296 + u32 clba; /* sectors per chunk */ 297 + u16 csecs; /* sector size */ 298 + u16 sos; /* out-of-band area size */ 285 299 286 - struct nvm_addr_format ppaf; 300 + /* device write constrains */ 301 + u32 ws_min; /* minimum write size */ 302 + u32 ws_opt; /* optimal write size */ 303 + u32 mw_cunits; /* distance required for successful read */ 287 304 288 - /* Legacy 1.2 specific geometry */ 289 - int plane_mode; /* drive device in single, double or quad mode */ 290 - int nr_planes; 291 - int sec_per_pg; /* only sectors for a single page */ 292 - int sec_per_pl; /* all sectors across planes */ 305 + /* device capabilities */ 306 + u32 mccap; 307 + 308 + /* device timings */ 309 + u32 trdt; /* Avg. Tread (ns) */ 310 + u32 trdm; /* Max Tread (ns) */ 311 + u32 tprt; /* Avg. Tprog (ns) */ 312 + u32 tprm; /* Max Tprog (ns) */ 313 + u32 tbet; /* Avg. Terase (ns) */ 314 + u32 tbem; /* Max Terase (ns) */ 315 + 316 + /* generic address format */ 317 + struct nvm_addrf addrf; 318 + 319 + /* 1.2 compatibility */ 320 + u8 vmnt; 321 + u32 cap; 322 + u32 dom; 323 + 324 + u8 mtype; 325 + u8 fmtype; 326 + 327 + u16 cpar; 328 + u32 mpos; 329 + 330 + u8 num_pln; 331 + u8 plane_mode; 332 + u16 num_pg; 333 + u16 fpg_sz; 293 334 }; 294 335 295 336 /* sub-device structure */ ··· 327 314 /* Base ppas for target LUNs */ 328 315 struct ppa_addr *luns; 329 316 330 - sector_t total_secs; 331 - 332 - struct nvm_id identity; 333 317 struct request_queue *q; 334 318 335 319 struct nvm_dev *parent; ··· 341 331 /* Device information */ 342 332 struct nvm_geo geo; 343 333 344 - unsigned long total_secs; 345 - 346 334 unsigned long *lun_map; 347 335 void *dma_pool; 348 - 349 - struct nvm_id identity; 350 336 351 337 /* Backend device */ 352 338 struct request_queue *q; ··· 363 357 struct ppa_addr r) 364 358 { 365 359 struct nvm_geo *geo = &tgt_dev->geo; 360 + struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf; 366 361 struct ppa_addr l; 367 362 368 - l.ppa = ((u64)r.g.blk) << geo->ppaf.blk_offset; 369 - l.ppa |= ((u64)r.g.pg) << geo->ppaf.pg_offset; 370 - l.ppa |= ((u64)r.g.sec) << geo->ppaf.sect_offset; 371 - l.ppa |= ((u64)r.g.pl) << geo->ppaf.pln_offset; 372 - l.ppa |= ((u64)r.g.lun) << geo->ppaf.lun_offset; 373 - l.ppa |= ((u64)r.g.ch) << geo->ppaf.ch_offset; 363 + l.ppa = ((u64)r.g.ch) << ppaf->ch_offset; 364 + l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset; 365 + l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset; 366 + l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset; 367 + l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset; 368 + l.ppa |= ((u64)r.g.sec) << ppaf->sect_offset; 374 369 375 370 return l; 376 371 } ··· 380 373 struct ppa_addr r) 381 374 { 382 375 struct nvm_geo *geo = &tgt_dev->geo; 376 + struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf; 383 377 struct ppa_addr l; 384 378 385 379 l.ppa = 0; 386 - /* 387 - * (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc. 388 - */ 389 - l.g.blk = (r.ppa >> geo->ppaf.blk_offset) & 390 - (((1 << geo->ppaf.blk_len) - 1)); 391 - l.g.pg |= (r.ppa >> geo->ppaf.pg_offset) & 392 - (((1 << geo->ppaf.pg_len) - 1)); 393 - l.g.sec |= (r.ppa >> geo->ppaf.sect_offset) & 394 - (((1 << geo->ppaf.sect_len) - 1)); 395 - l.g.pl |= (r.ppa >> geo->ppaf.pln_offset) & 396 - (((1 << geo->ppaf.pln_len) - 1)); 397 - l.g.lun |= (r.ppa >> geo->ppaf.lun_offset) & 398 - (((1 << geo->ppaf.lun_len) - 1)); 399 - l.g.ch |= (r.ppa >> geo->ppaf.ch_offset) & 400 - (((1 << geo->ppaf.ch_len) - 1)); 380 + 381 + l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset; 382 + l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset; 383 + l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset; 384 + l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset; 385 + l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset; 386 + l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sect_offset; 401 387 402 388 return l; 403 389 }