linux/include/linux/lightnvm.h
<<
>>
Prefs
   1#ifndef NVM_H
   2#define NVM_H
   3
   4#include <linux/types.h>
   5
   6enum {
   7        NVM_IO_OK = 0,
   8        NVM_IO_REQUEUE = 1,
   9        NVM_IO_DONE = 2,
  10        NVM_IO_ERR = 3,
  11
  12        NVM_IOTYPE_NONE = 0,
  13        NVM_IOTYPE_GC = 1,
  14};
  15
  16#define NVM_BLK_BITS (16)
  17#define NVM_PG_BITS  (16)
  18#define NVM_SEC_BITS (8)
  19#define NVM_PL_BITS  (8)
  20#define NVM_LUN_BITS (8)
  21#define NVM_CH_BITS  (8)
  22
  23struct ppa_addr {
  24        /* Generic structure for all addresses */
  25        union {
  26                struct {
  27                        u64 blk         : NVM_BLK_BITS;
  28                        u64 pg          : NVM_PG_BITS;
  29                        u64 sec         : NVM_SEC_BITS;
  30                        u64 pl          : NVM_PL_BITS;
  31                        u64 lun         : NVM_LUN_BITS;
  32                        u64 ch          : NVM_CH_BITS;
  33                } g;
  34
  35                u64 ppa;
  36        };
  37};
  38
  39struct nvm_rq;
  40struct nvm_id;
  41struct nvm_dev;
  42
  43typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *);
  44typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *);
  45typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *);
  46typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32,
  47                                nvm_l2p_update_fn *, void *);
  48typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int,
  49                                nvm_bb_update_fn *, void *);
  50typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int);
  51typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
  52typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *);
  53typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *);
  54typedef void (nvm_destroy_dma_pool_fn)(void *);
  55typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
  56                                                                dma_addr_t *);
  57typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
  58
  59struct nvm_dev_ops {
  60        nvm_id_fn               *identity;
  61        nvm_get_l2p_tbl_fn      *get_l2p_tbl;
  62        nvm_op_bb_tbl_fn        *get_bb_tbl;
  63        nvm_op_set_bb_fn        *set_bb_tbl;
  64
  65        nvm_submit_io_fn        *submit_io;
  66        nvm_erase_blk_fn        *erase_block;
  67
  68        nvm_create_dma_pool_fn  *create_dma_pool;
  69        nvm_destroy_dma_pool_fn *destroy_dma_pool;
  70        nvm_dev_dma_alloc_fn    *dev_dma_alloc;
  71        nvm_dev_dma_free_fn     *dev_dma_free;
  72
  73        unsigned int            max_phys_sect;
  74};
  75
  76
  77
  78#ifdef CONFIG_NVM
  79
  80#include <linux/blkdev.h>
  81#include <linux/file.h>
  82#include <linux/dmapool.h>
  83#include <uapi/linux/lightnvm.h>
  84
  85enum {
  86        /* HW Responsibilities */
  87        NVM_RSP_L2P     = 1 << 0,
  88        NVM_RSP_ECC     = 1 << 1,
  89
  90        /* Physical Adressing Mode */
  91        NVM_ADDRMODE_LINEAR     = 0,
  92        NVM_ADDRMODE_CHANNEL    = 1,
  93
  94        /* Plane programming mode for LUN */
  95        NVM_PLANE_SINGLE        = 1,
  96        NVM_PLANE_DOUBLE        = 2,
  97        NVM_PLANE_QUAD          = 4,
  98
  99        /* Status codes */
 100        NVM_RSP_SUCCESS         = 0x0,
 101        NVM_RSP_NOT_CHANGEABLE  = 0x1,
 102        NVM_RSP_ERR_FAILWRITE   = 0x40ff,
 103        NVM_RSP_ERR_EMPTYPAGE   = 0x42ff,
 104
 105        /* Device opcodes */
 106        NVM_OP_HBREAD           = 0x02,
 107        NVM_OP_HBWRITE          = 0x81,
 108        NVM_OP_PWRITE           = 0x91,
 109        NVM_OP_PREAD            = 0x92,
 110        NVM_OP_ERASE            = 0x90,
 111
 112        /* PPA Command Flags */
 113        NVM_IO_SNGL_ACCESS      = 0x0,
 114        NVM_IO_DUAL_ACCESS      = 0x1,
 115        NVM_IO_QUAD_ACCESS      = 0x2,
 116
 117        /* NAND Access Modes */
 118        NVM_IO_SUSPEND          = 0x80,
 119        NVM_IO_SLC_MODE         = 0x100,
 120        NVM_IO_SCRAMBLE_DISABLE = 0x200,
 121
 122        /* Block Types */
 123        NVM_BLK_T_FREE          = 0x0,
 124        NVM_BLK_T_BAD           = 0x1,
 125        NVM_BLK_T_GRWN_BAD      = 0x2,
 126        NVM_BLK_T_DEV           = 0x4,
 127        NVM_BLK_T_HOST          = 0x8,
 128
 129        /* Memory capabilities */
 130        NVM_ID_CAP_SLC          = 0x1,
 131        NVM_ID_CAP_CMD_SUSPEND  = 0x2,
 132        NVM_ID_CAP_SCRAMBLE     = 0x4,
 133        NVM_ID_CAP_ENCRYPT      = 0x8,
 134
 135        /* Memory types */
 136        NVM_ID_FMTYPE_SLC       = 0,
 137        NVM_ID_FMTYPE_MLC       = 1,
 138
 139        /* Device capabilities */
 140        NVM_ID_DCAP_BBLKMGMT    = 0x1,
 141        NVM_UD_DCAP_ECC         = 0x2,
 142};
 143
 144struct nvm_id_lp_mlc {
 145        u16     num_pairs;
 146        u8      pairs[886];
 147};
 148
 149struct nvm_id_lp_tbl {
 150        __u8    id[8];
 151        struct nvm_id_lp_mlc mlc;
 152};
 153
 154struct nvm_id_group {
 155        u8      mtype;
 156        u8      fmtype;
 157        u8      num_ch;
 158        u8      num_lun;
 159        u8      num_pln;
 160        u16     num_blk;
 161        u16     num_pg;
 162        u16     fpg_sz;
 163        u16     csecs;
 164        u16     sos;
 165        u32     trdt;
 166        u32     trdm;
 167        u32     tprt;
 168        u32     tprm;
 169        u32     tbet;
 170        u32     tbem;
 171        u32     mpos;
 172        u32     mccap;
 173        u16     cpar;
 174
 175        struct nvm_id_lp_tbl lptbl;
 176};
 177
 178struct nvm_addr_format {
 179        u8      ch_offset;
 180        u8      ch_len;
 181        u8      lun_offset;
 182        u8      lun_len;
 183        u8      pln_offset;
 184        u8      pln_len;
 185        u8      blk_offset;
 186        u8      blk_len;
 187        u8      pg_offset;
 188        u8      pg_len;
 189        u8      sect_offset;
 190        u8      sect_len;
 191};
 192
 193struct nvm_id {
 194        u8      ver_id;
 195        u8      vmnt;
 196        u8      cgrps;
 197        u32     cap;
 198        u32     dom;
 199        struct nvm_addr_format ppaf;
 200        struct nvm_id_group groups[4];
 201} __packed;
 202
 203struct nvm_target {
 204        struct list_head list;
 205        struct nvm_tgt_type *type;
 206        struct gendisk *disk;
 207};
 208
 209struct nvm_tgt_instance {
 210        struct nvm_tgt_type *tt;
 211};
 212
 213#define ADDR_EMPTY (~0ULL)
 214
 215#define NVM_VERSION_MAJOR 1
 216#define NVM_VERSION_MINOR 0
 217#define NVM_VERSION_PATCH 0
 218
 219struct nvm_rq;
 220typedef void (nvm_end_io_fn)(struct nvm_rq *);
 221
 222struct nvm_rq {
 223        struct nvm_tgt_instance *ins;
 224        struct nvm_dev *dev;
 225
 226        struct bio *bio;
 227
 228        union {
 229                struct ppa_addr ppa_addr;
 230                dma_addr_t dma_ppa_list;
 231        };
 232
 233        struct ppa_addr *ppa_list;
 234
 235        void *metadata;
 236        dma_addr_t dma_metadata;
 237
 238        struct completion *wait;
 239        nvm_end_io_fn *end_io;
 240
 241        uint8_t opcode;
 242        uint16_t nr_pages;
 243        uint16_t flags;
 244
 245        u64 ppa_status; /* ppa media status */
 246        int error;
 247};
 248
 249static inline struct nvm_rq *nvm_rq_from_pdu(void *pdu)
 250{
 251        return pdu - sizeof(struct nvm_rq);
 252}
 253
 254static inline void *nvm_rq_to_pdu(struct nvm_rq *rqdata)
 255{
 256        return rqdata + 1;
 257}
 258
 259struct nvm_block;
 260
 261struct nvm_lun {
 262        int id;
 263
 264        int lun_id;
 265        int chnl_id;
 266
 267        /* It is up to the target to mark blocks as closed. If the target does
 268         * not do it, all blocks are marked as open, and nr_open_blocks
 269         * represents the number of blocks in use
 270         */
 271        unsigned int nr_open_blocks;    /* Number of used, writable blocks */
 272        unsigned int nr_closed_blocks;  /* Number of used, read-only blocks */
 273        unsigned int nr_free_blocks;    /* Number of unused blocks */
 274        unsigned int nr_bad_blocks;     /* Number of bad blocks */
 275
 276        spinlock_t lock;
 277
 278        struct nvm_block *blocks;
 279};
 280
 281enum {
 282        NVM_BLK_ST_FREE =       0x1,    /* Free block */
 283        NVM_BLK_ST_OPEN =       0x2,    /* Open block - read-write */
 284        NVM_BLK_ST_CLOSED =     0x4,    /* Closed block - read-only */
 285        NVM_BLK_ST_BAD =        0x8,    /* Bad block */
 286};
 287
 288struct nvm_block {
 289        struct list_head list;
 290        struct nvm_lun *lun;
 291        unsigned long id;
 292
 293        void *priv;
 294        int state;
 295};
 296
 297/* system block cpu representation */
 298struct nvm_sb_info {
 299        unsigned long           seqnr;
 300        unsigned long           erase_cnt;
 301        unsigned int            version;
 302        char                    mmtype[NVM_MMTYPE_LEN];
 303        struct ppa_addr         fs_ppa;
 304};
 305
 306struct nvm_dev {
 307        struct nvm_dev_ops *ops;
 308
 309        struct list_head devices;
 310        struct list_head online_targets;
 311
 312        /* Media manager */
 313        struct nvmm_type *mt;
 314        void *mp;
 315
 316        /* System blocks */
 317        struct nvm_sb_info sb;
 318
 319        /* Device information */
 320        int nr_chnls;
 321        int nr_planes;
 322        int luns_per_chnl;
 323        int sec_per_pg; /* only sectors for a single page */
 324        int pgs_per_blk;
 325        int blks_per_lun;
 326        int sec_size;
 327        int oob_size;
 328        int mccap;
 329        struct nvm_addr_format ppaf;
 330
 331        /* Calculated/Cached values. These do not reflect the actual usable
 332         * blocks at run-time.
 333         */
 334        int max_rq_size;
 335        int plane_mode; /* drive device in single, double or quad mode */
 336
 337        int sec_per_pl; /* all sectors across planes */
 338        int sec_per_blk;
 339        int sec_per_lun;
 340
 341        /* lower page table */
 342        int lps_per_blk;
 343        int *lptbl;
 344
 345        unsigned long total_blocks;
 346        unsigned long total_secs;
 347        int nr_luns;
 348        unsigned max_pages_per_blk;
 349
 350        unsigned long *lun_map;
 351        void *ppalist_pool;
 352
 353        struct nvm_id identity;
 354
 355        /* Backend device */
 356        struct request_queue *q;
 357        char name[DISK_NAME_LEN];
 358
 359        struct mutex mlock;
 360        spinlock_t lock;
 361};
 362
 363static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev,
 364                                                struct ppa_addr r)
 365{
 366        struct ppa_addr l;
 367
 368        l.ppa = ((u64)r.g.blk) << dev->ppaf.blk_offset;
 369        l.ppa |= ((u64)r.g.pg) << dev->ppaf.pg_offset;
 370        l.ppa |= ((u64)r.g.sec) << dev->ppaf.sect_offset;
 371        l.ppa |= ((u64)r.g.pl) << dev->ppaf.pln_offset;
 372        l.ppa |= ((u64)r.g.lun) << dev->ppaf.lun_offset;
 373        l.ppa |= ((u64)r.g.ch) << dev->ppaf.ch_offset;
 374
 375        return l;
 376}
 377
 378static inline struct ppa_addr dev_to_generic_addr(struct nvm_dev *dev,
 379                                                struct ppa_addr r)
 380{
 381        struct ppa_addr l;
 382
 383        /*
 384         * (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc.
 385         */
 386        l.g.blk = (r.ppa >> dev->ppaf.blk_offset) &
 387                                        (((1 << dev->ppaf.blk_len) - 1));
 388        l.g.pg |= (r.ppa >> dev->ppaf.pg_offset) &
 389                                        (((1 << dev->ppaf.pg_len) - 1));
 390        l.g.sec |= (r.ppa >> dev->ppaf.sect_offset) &
 391                                        (((1 << dev->ppaf.sect_len) - 1));
 392        l.g.pl |= (r.ppa >> dev->ppaf.pln_offset) &
 393                                        (((1 << dev->ppaf.pln_len) - 1));
 394        l.g.lun |= (r.ppa >> dev->ppaf.lun_offset) &
 395                                        (((1 << dev->ppaf.lun_len) - 1));
 396        l.g.ch |= (r.ppa >> dev->ppaf.ch_offset) &
 397                                        (((1 << dev->ppaf.ch_len) - 1));
 398
 399        return l;
 400}
 401
 402static inline int ppa_empty(struct ppa_addr ppa_addr)
 403{
 404        return (ppa_addr.ppa == ADDR_EMPTY);
 405}
 406
 407static inline void ppa_set_empty(struct ppa_addr *ppa_addr)
 408{
 409        ppa_addr->ppa = ADDR_EMPTY;
 410}
 411
 412static inline struct ppa_addr block_to_ppa(struct nvm_dev *dev,
 413                                                        struct nvm_block *blk)
 414{
 415        struct ppa_addr ppa;
 416        struct nvm_lun *lun = blk->lun;
 417
 418        ppa.ppa = 0;
 419        ppa.g.blk = blk->id % dev->blks_per_lun;
 420        ppa.g.lun = lun->lun_id;
 421        ppa.g.ch = lun->chnl_id;
 422
 423        return ppa;
 424}
 425
 426static inline int ppa_to_slc(struct nvm_dev *dev, int slc_pg)
 427{
 428        return dev->lptbl[slc_pg];
 429}
 430
 431typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *);
 432typedef sector_t (nvm_tgt_capacity_fn)(void *);
 433typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int);
 434typedef void (nvm_tgt_exit_fn)(void *);
 435
 436struct nvm_tgt_type {
 437        const char *name;
 438        unsigned int version[3];
 439
 440        /* target entry points */
 441        nvm_tgt_make_rq_fn *make_rq;
 442        nvm_tgt_capacity_fn *capacity;
 443        nvm_end_io_fn *end_io;
 444
 445        /* module-specific init/teardown */
 446        nvm_tgt_init_fn *init;
 447        nvm_tgt_exit_fn *exit;
 448
 449        /* For internal use */
 450        struct list_head list;
 451};
 452
 453extern int nvm_register_target(struct nvm_tgt_type *);
 454extern void nvm_unregister_target(struct nvm_tgt_type *);
 455
 456extern void *nvm_dev_dma_alloc(struct nvm_dev *, gfp_t, dma_addr_t *);
 457extern void nvm_dev_dma_free(struct nvm_dev *, void *, dma_addr_t);
 458
 459typedef int (nvmm_register_fn)(struct nvm_dev *);
 460typedef void (nvmm_unregister_fn)(struct nvm_dev *);
 461typedef struct nvm_block *(nvmm_get_blk_fn)(struct nvm_dev *,
 462                                              struct nvm_lun *, unsigned long);
 463typedef void (nvmm_put_blk_fn)(struct nvm_dev *, struct nvm_block *);
 464typedef int (nvmm_open_blk_fn)(struct nvm_dev *, struct nvm_block *);
 465typedef int (nvmm_close_blk_fn)(struct nvm_dev *, struct nvm_block *);
 466typedef void (nvmm_flush_blk_fn)(struct nvm_dev *, struct nvm_block *);
 467typedef int (nvmm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
 468typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *,
 469                                                                unsigned long);
 470typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int);
 471typedef int (nvmm_reserve_lun)(struct nvm_dev *, int);
 472typedef void (nvmm_release_lun)(struct nvm_dev *, int);
 473typedef void (nvmm_lun_info_print_fn)(struct nvm_dev *);
 474
 475typedef int (nvmm_get_area_fn)(struct nvm_dev *, sector_t *, sector_t);
 476typedef void (nvmm_put_area_fn)(struct nvm_dev *, sector_t);
 477
 478struct nvmm_type {
 479        const char *name;
 480        unsigned int version[3];
 481
 482        nvmm_register_fn *register_mgr;
 483        nvmm_unregister_fn *unregister_mgr;
 484
 485        /* Block administration callbacks */
 486        nvmm_get_blk_fn *get_blk_unlocked;
 487        nvmm_put_blk_fn *put_blk_unlocked;
 488        nvmm_get_blk_fn *get_blk;
 489        nvmm_put_blk_fn *put_blk;
 490        nvmm_open_blk_fn *open_blk;
 491        nvmm_close_blk_fn *close_blk;
 492        nvmm_flush_blk_fn *flush_blk;
 493
 494        nvmm_submit_io_fn *submit_io;
 495        nvmm_erase_blk_fn *erase_blk;
 496
 497        /* Configuration management */
 498        nvmm_get_lun_fn *get_lun;
 499        nvmm_reserve_lun *reserve_lun;
 500        nvmm_release_lun *release_lun;
 501
 502        /* Statistics */
 503        nvmm_lun_info_print_fn *lun_info_print;
 504
 505        nvmm_get_area_fn *get_area;
 506        nvmm_put_area_fn *put_area;
 507
 508        struct list_head list;
 509};
 510
 511extern int nvm_register_mgr(struct nvmm_type *);
 512extern void nvm_unregister_mgr(struct nvmm_type *);
 513
 514extern struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *,
 515                                        struct nvm_lun *, unsigned long);
 516extern void nvm_put_blk_unlocked(struct nvm_dev *, struct nvm_block *);
 517
 518extern struct nvm_block *nvm_get_blk(struct nvm_dev *, struct nvm_lun *,
 519                                                                unsigned long);
 520extern void nvm_put_blk(struct nvm_dev *, struct nvm_block *);
 521
 522extern int nvm_register(struct request_queue *, char *,
 523                                                struct nvm_dev_ops *);
 524extern void nvm_unregister(char *);
 525
 526extern int nvm_submit_io(struct nvm_dev *, struct nvm_rq *);
 527extern void nvm_generic_to_addr_mode(struct nvm_dev *, struct nvm_rq *);
 528extern void nvm_addr_to_generic_mode(struct nvm_dev *, struct nvm_rq *);
 529extern int nvm_set_rqd_ppalist(struct nvm_dev *, struct nvm_rq *,
 530                                                        struct ppa_addr *, int);
 531extern void nvm_free_rqd_ppalist(struct nvm_dev *, struct nvm_rq *);
 532extern int nvm_erase_ppa(struct nvm_dev *, struct ppa_addr *, int);
 533extern int nvm_erase_blk(struct nvm_dev *, struct nvm_block *);
 534extern void nvm_end_io(struct nvm_rq *, int);
 535extern int nvm_submit_ppa(struct nvm_dev *, struct ppa_addr *, int, int, int,
 536                                                                void *, int);
 537
 538/* sysblk.c */
 539#define NVM_SYSBLK_MAGIC 0x4E564D53 /* "NVMS" */
 540
 541/* system block on disk representation */
 542struct nvm_system_block {
 543        __be32                  magic;          /* magic signature */
 544        __be32                  seqnr;          /* sequence number */
 545        __be32                  erase_cnt;      /* erase count */
 546        __be16                  version;        /* version number */
 547        u8                      mmtype[NVM_MMTYPE_LEN]; /* media manager name */
 548        __be64                  fs_ppa;         /* PPA for media manager
 549                                                 * superblock */
 550};
 551
 552extern int nvm_get_sysblock(struct nvm_dev *, struct nvm_sb_info *);
 553extern int nvm_update_sysblock(struct nvm_dev *, struct nvm_sb_info *);
 554extern int nvm_init_sysblock(struct nvm_dev *, struct nvm_sb_info *);
 555
 556extern int nvm_dev_factory(struct nvm_dev *, int flags);
 557#else /* CONFIG_NVM */
 558struct nvm_dev_ops;
 559
 560static inline int nvm_register(struct request_queue *q, char *disk_name,
 561                                                        struct nvm_dev_ops *ops)
 562{
 563        return -EINVAL;
 564}
 565static inline void nvm_unregister(char *disk_name) {}
 566#endif /* CONFIG_NVM */
 567#endif /* LIGHTNVM.H */
 568