diff options
Diffstat (limited to 'drivers/lightnvm/pblk-init.c')
-rw-r--r-- | drivers/lightnvm/pblk-init.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c index 27b4974930b4..91a5bc2556a3 100644 --- a/drivers/lightnvm/pblk-init.c +++ b/drivers/lightnvm/pblk-init.c | |||
@@ -229,20 +229,62 @@ static int pblk_set_addrf_12(struct nvm_geo *geo, struct nvm_addrf_12 *dst) | |||
229 | return dst->blk_offset + src->blk_len; | 229 | return dst->blk_offset + src->blk_len; |
230 | } | 230 | } |
231 | 231 | ||
232 | static int pblk_set_addrf_20(struct nvm_geo *geo, struct nvm_addrf *adst, | ||
233 | struct pblk_addrf *udst) | ||
234 | { | ||
235 | struct nvm_addrf *src = &geo->addrf; | ||
236 | |||
237 | adst->ch_len = get_count_order(geo->num_ch); | ||
238 | adst->lun_len = get_count_order(geo->num_lun); | ||
239 | adst->chk_len = src->chk_len; | ||
240 | adst->sec_len = src->sec_len; | ||
241 | |||
242 | adst->sec_offset = 0; | ||
243 | adst->ch_offset = adst->sec_len; | ||
244 | adst->lun_offset = adst->ch_offset + adst->ch_len; | ||
245 | adst->chk_offset = adst->lun_offset + adst->lun_len; | ||
246 | |||
247 | adst->sec_mask = ((1ULL << adst->sec_len) - 1) << adst->sec_offset; | ||
248 | adst->chk_mask = ((1ULL << adst->chk_len) - 1) << adst->chk_offset; | ||
249 | adst->lun_mask = ((1ULL << adst->lun_len) - 1) << adst->lun_offset; | ||
250 | adst->ch_mask = ((1ULL << adst->ch_len) - 1) << adst->ch_offset; | ||
251 | |||
252 | udst->sec_stripe = geo->ws_opt; | ||
253 | udst->ch_stripe = geo->num_ch; | ||
254 | udst->lun_stripe = geo->num_lun; | ||
255 | |||
256 | udst->sec_lun_stripe = udst->sec_stripe * udst->ch_stripe; | ||
257 | udst->sec_ws_stripe = udst->sec_lun_stripe * udst->lun_stripe; | ||
258 | |||
259 | return adst->chk_offset + adst->chk_len; | ||
260 | } | ||
261 | |||
232 | static int pblk_set_addrf(struct pblk *pblk) | 262 | static int pblk_set_addrf(struct pblk *pblk) |
233 | { | 263 | { |
234 | struct nvm_tgt_dev *dev = pblk->dev; | 264 | struct nvm_tgt_dev *dev = pblk->dev; |
235 | struct nvm_geo *geo = &dev->geo; | 265 | struct nvm_geo *geo = &dev->geo; |
236 | int mod; | 266 | int mod; |
237 | 267 | ||
238 | div_u64_rem(geo->clba, pblk->min_write_pgs, &mod); | 268 | switch (geo->version) { |
239 | if (mod) { | 269 | case NVM_OCSSD_SPEC_12: |
240 | pr_err("pblk: bad configuration of sectors/pages\n"); | 270 | div_u64_rem(geo->clba, pblk->min_write_pgs, &mod); |
271 | if (mod) { | ||
272 | pr_err("pblk: bad configuration of sectors/pages\n"); | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | |||
276 | pblk->addrf_len = pblk_set_addrf_12(geo, (void *)&pblk->addrf); | ||
277 | break; | ||
278 | case NVM_OCSSD_SPEC_20: | ||
279 | pblk->addrf_len = pblk_set_addrf_20(geo, (void *)&pblk->addrf, | ||
280 | &pblk->uaddrf); | ||
281 | break; | ||
282 | default: | ||
283 | pr_err("pblk: OCSSD revision not supported (%d)\n", | ||
284 | geo->version); | ||
241 | return -EINVAL; | 285 | return -EINVAL; |
242 | } | 286 | } |
243 | 287 | ||
244 | pblk->addrf_len = pblk_set_addrf_12(geo, (void *)&pblk->addrf); | ||
245 | |||
246 | return 0; | 288 | return 0; |
247 | } | 289 | } |
248 | 290 | ||
@@ -1110,7 +1152,9 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk, | |||
1110 | struct pblk *pblk; | 1152 | struct pblk *pblk; |
1111 | int ret; | 1153 | int ret; |
1112 | 1154 | ||
1113 | if (geo->version != NVM_OCSSD_SPEC_12) { | 1155 | /* pblk supports 1.2 and 2.0 versions */ |
1156 | if (!(geo->version == NVM_OCSSD_SPEC_12 || | ||
1157 | geo->version == NVM_OCSSD_SPEC_20)) { | ||
1114 | pr_err("pblk: OCSSD version not supported (%u)\n", | 1158 | pr_err("pblk: OCSSD version not supported (%u)\n", |
1115 | geo->version); | 1159 | geo->version); |
1116 | return ERR_PTR(-EINVAL); | 1160 | return ERR_PTR(-EINVAL); |