]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/lightnvm/rrpc.h
Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[karo-tx-linux.git] / drivers / lightnvm / rrpc.h
index bed49baa784101b0bd56b9b92abea18eb65973f2..94e4d73116b2948888a7539cded74e198b412634 100644 (file)
@@ -52,9 +52,11 @@ struct rrpc_rq {
 };
 
 struct rrpc_block {
-       struct nvm_block *parent;
+       int id;                         /* id inside of LUN */
        struct rrpc_lun *rlun;
-       struct list_head prio;
+
+       struct list_head prio;          /* LUN CG list */
+       struct list_head list;          /* LUN free, used, bb list */
 
 #define MAX_INVALID_PAGES_STORAGE 8
        /* Bitmap for invalid page intries */
@@ -64,21 +66,38 @@ struct rrpc_block {
        /* number of pages that are invalid, wrt host page size */
        unsigned int nr_invalid_pages;
 
+       int state;
+
        spinlock_t lock;
        atomic_t data_cmnt_size; /* data pages committed to stable storage */
 };
 
 struct rrpc_lun {
        struct rrpc *rrpc;
-       struct nvm_lun *parent;
+
+       int id;
+       struct ppa_addr bppa;
+
        struct rrpc_block *cur, *gc_cur;
        struct rrpc_block *blocks;      /* Reference to block allocation */
 
        struct list_head prio_list;     /* Blocks that may be GC'ed */
        struct list_head wblk_list;     /* Queued blocks to be written to */
 
+       /* lun block lists */
+       struct list_head used_list;     /* In-use blocks */
+       struct list_head free_list;     /* Not used blocks i.e. released
+                                        * and ready for use
+                                        */
+       struct list_head bb_list;       /* Bad blocks. Mutually exclusive with
+                                        * free_list and used_list
+                                        */
+       unsigned int nr_free_blocks;    /* Number of unused blocks */
+
        struct work_struct ws_gc;
 
+       int reserved_blocks;
+
        spinlock_t lock;
 };
 
@@ -86,11 +105,10 @@ struct rrpc {
        /* instance must be kept in top to resolve rrpc in unprep */
        struct nvm_tgt_instance instance;
 
-       struct nvm_dev *dev;
+       struct nvm_tgt_dev *dev;
        struct gendisk *disk;
 
        sector_t soffset; /* logical sector offset */
-       u64 poffset; /* physical page offset */
 
        int nr_luns;
        struct rrpc_lun *luns;
@@ -147,13 +165,37 @@ struct rrpc_rev_addr {
        u64 addr;
 };
 
-static inline struct rrpc_block *rrpc_get_rblk(struct rrpc_lun *rlun,
-                                                               int blk_id)
+static inline struct ppa_addr rrpc_linear_to_generic_addr(struct nvm_geo *geo,
+                                                         struct ppa_addr r)
+{
+       struct ppa_addr l;
+       int secs, pgs;
+       sector_t ppa = r.ppa;
+
+       l.ppa = 0;
+
+       div_u64_rem(ppa, geo->sec_per_pg, &secs);
+       l.g.sec = secs;
+
+       sector_div(ppa, geo->sec_per_pg);
+       div_u64_rem(ppa, geo->pgs_per_blk, &pgs);
+       l.g.pg = pgs;
+
+       return l;
+}
+
+static inline struct ppa_addr rrpc_recov_addr(struct nvm_tgt_dev *dev, u64 pba)
+{
+       return linear_to_generic_addr(&dev->geo, pba);
+}
+
+static inline u64 rrpc_blk_to_ppa(struct rrpc *rrpc, struct rrpc_block *rblk)
 {
-       struct rrpc *rrpc = rlun->rrpc;
-       int lun_blk = blk_id % rrpc->dev->blks_per_lun;
+       struct nvm_tgt_dev *dev = rrpc->dev;
+       struct nvm_geo *geo = &dev->geo;
+       struct rrpc_lun *rlun = rblk->rlun;
 
-       return &rlun->blocks[lun_blk];
+       return (rlun->id * geo->sec_per_lun) + (rblk->id * geo->sec_per_blk);
 }
 
 static inline sector_t rrpc_get_laddr(struct bio *bio)