at v4.4 10 kB view raw
1#ifndef NVM_H 2#define NVM_H 3 4enum { 5 NVM_IO_OK = 0, 6 NVM_IO_REQUEUE = 1, 7 NVM_IO_DONE = 2, 8 NVM_IO_ERR = 3, 9 10 NVM_IOTYPE_NONE = 0, 11 NVM_IOTYPE_GC = 1, 12}; 13 14#ifdef CONFIG_NVM 15 16#include <linux/blkdev.h> 17#include <linux/types.h> 18#include <linux/file.h> 19#include <linux/dmapool.h> 20 21enum { 22 /* HW Responsibilities */ 23 NVM_RSP_L2P = 1 << 0, 24 NVM_RSP_ECC = 1 << 1, 25 26 /* Physical Adressing Mode */ 27 NVM_ADDRMODE_LINEAR = 0, 28 NVM_ADDRMODE_CHANNEL = 1, 29 30 /* Plane programming mode for LUN */ 31 NVM_PLANE_SINGLE = 0, 32 NVM_PLANE_DOUBLE = 1, 33 NVM_PLANE_QUAD = 2, 34 35 /* Status codes */ 36 NVM_RSP_SUCCESS = 0x0, 37 NVM_RSP_NOT_CHANGEABLE = 0x1, 38 NVM_RSP_ERR_FAILWRITE = 0x40ff, 39 NVM_RSP_ERR_EMPTYPAGE = 0x42ff, 40 41 /* Device opcodes */ 42 NVM_OP_HBREAD = 0x02, 43 NVM_OP_HBWRITE = 0x81, 44 NVM_OP_PWRITE = 0x91, 45 NVM_OP_PREAD = 0x92, 46 NVM_OP_ERASE = 0x90, 47 48 /* PPA Command Flags */ 49 NVM_IO_SNGL_ACCESS = 0x0, 50 NVM_IO_DUAL_ACCESS = 0x1, 51 NVM_IO_QUAD_ACCESS = 0x2, 52 53 /* NAND Access Modes */ 54 NVM_IO_SUSPEND = 0x80, 55 NVM_IO_SLC_MODE = 0x100, 56 NVM_IO_SCRAMBLE_DISABLE = 0x200, 57 58 /* Block Types */ 59 NVM_BLK_T_FREE = 0x0, 60 NVM_BLK_T_BAD = 0x1, 61 NVM_BLK_T_DEV = 0x2, 62 NVM_BLK_T_HOST = 0x4, 63}; 64 65struct nvm_id_group { 66 u8 mtype; 67 u8 fmtype; 68 u8 num_ch; 69 u8 num_lun; 70 u8 num_pln; 71 u16 num_blk; 72 u16 num_pg; 73 u16 fpg_sz; 74 u16 csecs; 75 u16 sos; 76 u32 trdt; 77 u32 trdm; 78 u32 tprt; 79 u32 tprm; 80 u32 tbet; 81 u32 tbem; 82 u32 mpos; 83 u32 mccap; 84 u16 cpar; 85}; 86 87struct nvm_addr_format { 88 u8 ch_offset; 89 u8 ch_len; 90 u8 lun_offset; 91 u8 lun_len; 92 u8 pln_offset; 93 u8 pln_len; 94 u8 blk_offset; 95 u8 blk_len; 96 u8 pg_offset; 97 u8 pg_len; 98 u8 sect_offset; 99 u8 sect_len; 100}; 101 102struct nvm_id { 103 u8 ver_id; 104 u8 vmnt; 105 u8 cgrps; 106 u32 cap; 107 u32 dom; 108 struct nvm_addr_format ppaf; 109 struct nvm_id_group groups[4]; 110} __packed; 111 112struct nvm_target { 113 struct list_head list; 114 struct nvm_tgt_type *type; 115 struct gendisk *disk; 116}; 117 118struct nvm_tgt_instance { 119 struct nvm_tgt_type *tt; 120}; 121 122#define ADDR_EMPTY (~0ULL) 123 124#define NVM_VERSION_MAJOR 1 125#define NVM_VERSION_MINOR 0 126#define NVM_VERSION_PATCH 0 127 128#define NVM_BLK_BITS (16) 129#define NVM_PG_BITS (16) 130#define NVM_SEC_BITS (8) 131#define NVM_PL_BITS (8) 132#define NVM_LUN_BITS (8) 133#define NVM_CH_BITS (8) 134 135struct ppa_addr { 136 /* Generic structure for all addresses */ 137 union { 138 struct { 139 u64 blk : NVM_BLK_BITS; 140 u64 pg : NVM_PG_BITS; 141 u64 sec : NVM_SEC_BITS; 142 u64 pl : NVM_PL_BITS; 143 u64 lun : NVM_LUN_BITS; 144 u64 ch : NVM_CH_BITS; 145 } g; 146 147 u64 ppa; 148 }; 149}; 150 151struct nvm_rq { 152 struct nvm_tgt_instance *ins; 153 struct nvm_dev *dev; 154 155 struct bio *bio; 156 157 union { 158 struct ppa_addr ppa_addr; 159 dma_addr_t dma_ppa_list; 160 }; 161 162 struct ppa_addr *ppa_list; 163 164 void *metadata; 165 dma_addr_t dma_metadata; 166 167 uint8_t opcode; 168 uint16_t nr_pages; 169 uint16_t flags; 170}; 171 172static inline struct nvm_rq *nvm_rq_from_pdu(void *pdu) 173{ 174 return pdu - sizeof(struct nvm_rq); 175} 176 177static inline void *nvm_rq_to_pdu(struct nvm_rq *rqdata) 178{ 179 return rqdata + 1; 180} 181 182struct nvm_block; 183 184typedef int (nvm_l2p_update_fn)(u64, u32, __le64 *, void *); 185typedef int (nvm_bb_update_fn)(struct ppa_addr, int, u8 *, void *); 186typedef int (nvm_id_fn)(struct nvm_dev *, struct nvm_id *); 187typedef int (nvm_get_l2p_tbl_fn)(struct nvm_dev *, u64, u32, 188 nvm_l2p_update_fn *, void *); 189typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, int, 190 nvm_bb_update_fn *, void *); 191typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct nvm_rq *, int); 192typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *); 193typedef int (nvm_erase_blk_fn)(struct nvm_dev *, struct nvm_rq *); 194typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *); 195typedef void (nvm_destroy_dma_pool_fn)(void *); 196typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t, 197 dma_addr_t *); 198typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t); 199 200struct nvm_dev_ops { 201 nvm_id_fn *identity; 202 nvm_get_l2p_tbl_fn *get_l2p_tbl; 203 nvm_op_bb_tbl_fn *get_bb_tbl; 204 nvm_op_set_bb_fn *set_bb_tbl; 205 206 nvm_submit_io_fn *submit_io; 207 nvm_erase_blk_fn *erase_block; 208 209 nvm_create_dma_pool_fn *create_dma_pool; 210 nvm_destroy_dma_pool_fn *destroy_dma_pool; 211 nvm_dev_dma_alloc_fn *dev_dma_alloc; 212 nvm_dev_dma_free_fn *dev_dma_free; 213 214 unsigned int max_phys_sect; 215}; 216 217struct nvm_lun { 218 int id; 219 220 int lun_id; 221 int chnl_id; 222 223 unsigned int nr_inuse_blocks; /* Number of used blocks */ 224 unsigned int nr_free_blocks; /* Number of unused blocks */ 225 unsigned int nr_bad_blocks; /* Number of bad blocks */ 226 struct nvm_block *blocks; 227 228 spinlock_t lock; 229}; 230 231struct nvm_block { 232 struct list_head list; 233 struct nvm_lun *lun; 234 unsigned long id; 235 236 void *priv; 237 int type; 238}; 239 240struct nvm_dev { 241 struct nvm_dev_ops *ops; 242 243 struct list_head devices; 244 struct list_head online_targets; 245 246 /* Media manager */ 247 struct nvmm_type *mt; 248 void *mp; 249 250 /* Device information */ 251 int nr_chnls; 252 int nr_planes; 253 int luns_per_chnl; 254 int sec_per_pg; /* only sectors for a single page */ 255 int pgs_per_blk; 256 int blks_per_lun; 257 int sec_size; 258 int oob_size; 259 struct nvm_addr_format ppaf; 260 261 /* Calculated/Cached values. These do not reflect the actual usable 262 * blocks at run-time. 263 */ 264 int max_rq_size; 265 int plane_mode; /* drive device in single, double or quad mode */ 266 267 int sec_per_pl; /* all sectors across planes */ 268 int sec_per_blk; 269 int sec_per_lun; 270 271 unsigned long total_pages; 272 unsigned long total_blocks; 273 int nr_luns; 274 unsigned max_pages_per_blk; 275 276 void *ppalist_pool; 277 278 struct nvm_id identity; 279 280 /* Backend device */ 281 struct request_queue *q; 282 char name[DISK_NAME_LEN]; 283}; 284 285static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev, 286 struct ppa_addr r) 287{ 288 struct ppa_addr l; 289 290 l.ppa = ((u64)r.g.blk) << dev->ppaf.blk_offset; 291 l.ppa |= ((u64)r.g.pg) << dev->ppaf.pg_offset; 292 l.ppa |= ((u64)r.g.sec) << dev->ppaf.sect_offset; 293 l.ppa |= ((u64)r.g.pl) << dev->ppaf.pln_offset; 294 l.ppa |= ((u64)r.g.lun) << dev->ppaf.lun_offset; 295 l.ppa |= ((u64)r.g.ch) << dev->ppaf.ch_offset; 296 297 return l; 298} 299 300static inline struct ppa_addr dev_to_generic_addr(struct nvm_dev *dev, 301 struct ppa_addr r) 302{ 303 struct ppa_addr l; 304 305 /* 306 * (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc. 307 */ 308 l.g.blk = (r.ppa >> dev->ppaf.blk_offset) & 309 (((1 << dev->ppaf.blk_len) - 1)); 310 l.g.pg |= (r.ppa >> dev->ppaf.pg_offset) & 311 (((1 << dev->ppaf.pg_len) - 1)); 312 l.g.sec |= (r.ppa >> dev->ppaf.sect_offset) & 313 (((1 << dev->ppaf.sect_len) - 1)); 314 l.g.pl |= (r.ppa >> dev->ppaf.pln_offset) & 315 (((1 << dev->ppaf.pln_len) - 1)); 316 l.g.lun |= (r.ppa >> dev->ppaf.lun_offset) & 317 (((1 << dev->ppaf.lun_len) - 1)); 318 l.g.ch |= (r.ppa >> dev->ppaf.ch_offset) & 319 (((1 << dev->ppaf.ch_len) - 1)); 320 321 return l; 322} 323 324static inline int ppa_empty(struct ppa_addr ppa_addr) 325{ 326 return (ppa_addr.ppa == ADDR_EMPTY); 327} 328 329static inline void ppa_set_empty(struct ppa_addr *ppa_addr) 330{ 331 ppa_addr->ppa = ADDR_EMPTY; 332} 333 334static inline struct ppa_addr block_to_ppa(struct nvm_dev *dev, 335 struct nvm_block *blk) 336{ 337 struct ppa_addr ppa; 338 struct nvm_lun *lun = blk->lun; 339 340 ppa.ppa = 0; 341 ppa.g.blk = blk->id % dev->blks_per_lun; 342 ppa.g.lun = lun->lun_id; 343 ppa.g.ch = lun->chnl_id; 344 345 return ppa; 346} 347 348typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *); 349typedef sector_t (nvm_tgt_capacity_fn)(void *); 350typedef int (nvm_tgt_end_io_fn)(struct nvm_rq *, int); 351typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int); 352typedef void (nvm_tgt_exit_fn)(void *); 353 354struct nvm_tgt_type { 355 const char *name; 356 unsigned int version[3]; 357 358 /* target entry points */ 359 nvm_tgt_make_rq_fn *make_rq; 360 nvm_tgt_capacity_fn *capacity; 361 nvm_tgt_end_io_fn *end_io; 362 363 /* module-specific init/teardown */ 364 nvm_tgt_init_fn *init; 365 nvm_tgt_exit_fn *exit; 366 367 /* For internal use */ 368 struct list_head list; 369}; 370 371extern int nvm_register_target(struct nvm_tgt_type *); 372extern void nvm_unregister_target(struct nvm_tgt_type *); 373 374extern void *nvm_dev_dma_alloc(struct nvm_dev *, gfp_t, dma_addr_t *); 375extern void nvm_dev_dma_free(struct nvm_dev *, void *, dma_addr_t); 376 377typedef int (nvmm_register_fn)(struct nvm_dev *); 378typedef void (nvmm_unregister_fn)(struct nvm_dev *); 379typedef struct nvm_block *(nvmm_get_blk_fn)(struct nvm_dev *, 380 struct nvm_lun *, unsigned long); 381typedef void (nvmm_put_blk_fn)(struct nvm_dev *, struct nvm_block *); 382typedef int (nvmm_open_blk_fn)(struct nvm_dev *, struct nvm_block *); 383typedef int (nvmm_close_blk_fn)(struct nvm_dev *, struct nvm_block *); 384typedef void (nvmm_flush_blk_fn)(struct nvm_dev *, struct nvm_block *); 385typedef int (nvmm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *); 386typedef int (nvmm_end_io_fn)(struct nvm_rq *, int); 387typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *, 388 unsigned long); 389typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int); 390typedef void (nvmm_lun_info_print_fn)(struct nvm_dev *); 391 392struct nvmm_type { 393 const char *name; 394 unsigned int version[3]; 395 396 nvmm_register_fn *register_mgr; 397 nvmm_unregister_fn *unregister_mgr; 398 399 /* Block administration callbacks */ 400 nvmm_get_blk_fn *get_blk; 401 nvmm_put_blk_fn *put_blk; 402 nvmm_open_blk_fn *open_blk; 403 nvmm_close_blk_fn *close_blk; 404 nvmm_flush_blk_fn *flush_blk; 405 406 nvmm_submit_io_fn *submit_io; 407 nvmm_end_io_fn *end_io; 408 nvmm_erase_blk_fn *erase_blk; 409 410 /* Configuration management */ 411 nvmm_get_lun_fn *get_lun; 412 413 /* Statistics */ 414 nvmm_lun_info_print_fn *lun_info_print; 415 struct list_head list; 416}; 417 418extern int nvm_register_mgr(struct nvmm_type *); 419extern void nvm_unregister_mgr(struct nvmm_type *); 420 421extern struct nvm_block *nvm_get_blk(struct nvm_dev *, struct nvm_lun *, 422 unsigned long); 423extern void nvm_put_blk(struct nvm_dev *, struct nvm_block *); 424 425extern int nvm_register(struct request_queue *, char *, 426 struct nvm_dev_ops *); 427extern void nvm_unregister(char *); 428 429extern int nvm_submit_io(struct nvm_dev *, struct nvm_rq *); 430extern int nvm_erase_blk(struct nvm_dev *, struct nvm_block *); 431#else /* CONFIG_NVM */ 432struct nvm_dev_ops; 433 434static inline int nvm_register(struct request_queue *q, char *disk_name, 435 struct nvm_dev_ops *ops) 436{ 437 return -EINVAL; 438} 439static inline void nvm_unregister(char *disk_name) {} 440#endif /* CONFIG_NVM */ 441#endif /* LIGHTNVM.H */