aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/rrpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lightnvm/rrpc.c')
-rw-r--r--drivers/lightnvm/rrpc.c57
1 files changed, 52 insertions, 5 deletions
diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c
index 7ba64c87ba1c..134e4faba482 100644
--- a/drivers/lightnvm/rrpc.c
+++ b/drivers/lightnvm/rrpc.c
@@ -123,12 +123,42 @@ static u64 block_to_addr(struct rrpc *rrpc, struct rrpc_block *rblk)
123 return blk->id * rrpc->dev->pgs_per_blk; 123 return blk->id * rrpc->dev->pgs_per_blk;
124} 124}
125 125
126static struct ppa_addr linear_to_generic_addr(struct nvm_dev *dev,
127 struct ppa_addr r)
128{
129 struct ppa_addr l;
130 int secs, pgs, blks, luns;
131 sector_t ppa = r.ppa;
132
133 l.ppa = 0;
134
135 div_u64_rem(ppa, dev->sec_per_pg, &secs);
136 l.g.sec = secs;
137
138 sector_div(ppa, dev->sec_per_pg);
139 div_u64_rem(ppa, dev->sec_per_blk, &pgs);
140 l.g.pg = pgs;
141
142 sector_div(ppa, dev->pgs_per_blk);
143 div_u64_rem(ppa, dev->blks_per_lun, &blks);
144 l.g.blk = blks;
145
146 sector_div(ppa, dev->blks_per_lun);
147 div_u64_rem(ppa, dev->luns_per_chnl, &luns);
148 l.g.lun = luns;
149
150 sector_div(ppa, dev->luns_per_chnl);
151 l.g.ch = ppa;
152
153 return l;
154}
155
126static struct ppa_addr rrpc_ppa_to_gaddr(struct nvm_dev *dev, u64 addr) 156static struct ppa_addr rrpc_ppa_to_gaddr(struct nvm_dev *dev, u64 addr)
127{ 157{
128 struct ppa_addr paddr; 158 struct ppa_addr paddr;
129 159
130 paddr.ppa = addr; 160 paddr.ppa = addr;
131 return __linear_to_generic_addr(dev, paddr); 161 return linear_to_generic_addr(dev, paddr);
132} 162}
133 163
134/* requires lun->lock taken */ 164/* requires lun->lock taken */
@@ -152,7 +182,7 @@ static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
152 struct nvm_block *blk; 182 struct nvm_block *blk;
153 struct rrpc_block *rblk; 183 struct rrpc_block *rblk;
154 184
155 blk = nvm_get_blk(rrpc->dev, rlun->parent, 0); 185 blk = nvm_get_blk(rrpc->dev, rlun->parent, flags);
156 if (!blk) 186 if (!blk)
157 return NULL; 187 return NULL;
158 188
@@ -172,6 +202,20 @@ static void rrpc_put_blk(struct rrpc *rrpc, struct rrpc_block *rblk)
172 nvm_put_blk(rrpc->dev, rblk->parent); 202 nvm_put_blk(rrpc->dev, rblk->parent);
173} 203}
174 204
205static void rrpc_put_blks(struct rrpc *rrpc)
206{
207 struct rrpc_lun *rlun;
208 int i;
209
210 for (i = 0; i < rrpc->nr_luns; i++) {
211 rlun = &rrpc->luns[i];
212 if (rlun->cur)
213 rrpc_put_blk(rrpc, rlun->cur);
214 if (rlun->gc_cur)
215 rrpc_put_blk(rrpc, rlun->gc_cur);
216 }
217}
218
175static struct rrpc_lun *get_next_lun(struct rrpc *rrpc) 219static struct rrpc_lun *get_next_lun(struct rrpc *rrpc)
176{ 220{
177 int next = atomic_inc_return(&rrpc->next_lun); 221 int next = atomic_inc_return(&rrpc->next_lun);
@@ -972,7 +1016,7 @@ static int rrpc_map_init(struct rrpc *rrpc)
972 return 0; 1016 return 0;
973 1017
974 /* Bring up the mapping table from device */ 1018 /* Bring up the mapping table from device */
975 ret = dev->ops->get_l2p_tbl(dev->q, 0, dev->total_pages, 1019 ret = dev->ops->get_l2p_tbl(dev, 0, dev->total_pages,
976 rrpc_l2p_update, rrpc); 1020 rrpc_l2p_update, rrpc);
977 if (ret) { 1021 if (ret) {
978 pr_err("nvm: rrpc: could not read L2P table.\n"); 1022 pr_err("nvm: rrpc: could not read L2P table.\n");
@@ -1194,18 +1238,21 @@ static int rrpc_luns_configure(struct rrpc *rrpc)
1194 1238
1195 rblk = rrpc_get_blk(rrpc, rlun, 0); 1239 rblk = rrpc_get_blk(rrpc, rlun, 0);
1196 if (!rblk) 1240 if (!rblk)
1197 return -EINVAL; 1241 goto err;
1198 1242
1199 rrpc_set_lun_cur(rlun, rblk); 1243 rrpc_set_lun_cur(rlun, rblk);
1200 1244
1201 /* Emergency gc block */ 1245 /* Emergency gc block */
1202 rblk = rrpc_get_blk(rrpc, rlun, 1); 1246 rblk = rrpc_get_blk(rrpc, rlun, 1);
1203 if (!rblk) 1247 if (!rblk)
1204 return -EINVAL; 1248 goto err;
1205 rlun->gc_cur = rblk; 1249 rlun->gc_cur = rblk;
1206 } 1250 }
1207 1251
1208 return 0; 1252 return 0;
1253err:
1254 rrpc_put_blks(rrpc);
1255 return -EINVAL;
1209} 1256}
1210 1257
1211static struct nvm_tgt_type tt_rrpc; 1258static struct nvm_tgt_type tt_rrpc;