Blame view

include/linux/lightnvm.h 14.8 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  /* SPDX-License-Identifier: GPL-2.0 */
cd9e9808d   Matias Bjørling   lightnvm: Support...
2
3
  #ifndef NVM_H
  #define NVM_H
b76eb20bb   Matias Bjørling   lightnvm: move ta...
4
  #include <linux/blkdev.h>
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
5
  #include <linux/types.h>
b76eb20bb   Matias Bjørling   lightnvm: move ta...
6
  #include <uapi/linux/lightnvm.h>
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
7

cd9e9808d   Matias Bjørling   lightnvm: Support...
8
9
10
11
12
13
14
15
16
  enum {
  	NVM_IO_OK = 0,
  	NVM_IO_REQUEUE = 1,
  	NVM_IO_DONE = 2,
  	NVM_IO_ERR = 3,
  
  	NVM_IOTYPE_NONE = 0,
  	NVM_IOTYPE_GC = 1,
  };
694715137   Javier González   lightnvm: add sup...
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  /* common format */
  #define NVM_GEN_CH_BITS  (8)
  #define NVM_GEN_LUN_BITS (8)
  #define NVM_GEN_BLK_BITS (16)
  #define NVM_GEN_RESERVED (32)
  
  /* 1.2 format */
  #define NVM_12_PG_BITS  (16)
  #define NVM_12_PL_BITS  (4)
  #define NVM_12_SEC_BITS (4)
  #define NVM_12_RESERVED (8)
  
  /* 2.0 format */
  #define NVM_20_SEC_BITS (24)
  #define NVM_20_RESERVED (8)
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
32

f1d4e8121   Javier González   lightnvm: add sho...
33
34
35
36
  enum {
  	NVM_OCSSD_SPEC_12 = 12,
  	NVM_OCSSD_SPEC_20 = 20,
  };
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
37
38
39
  struct ppa_addr {
  	/* Generic structure for all addresses */
  	union {
694715137   Javier González   lightnvm: add sup...
40
  		/* generic device format */
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
41
  		struct {
694715137   Javier González   lightnvm: add sup...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  			u64 ch		: NVM_GEN_CH_BITS;
  			u64 lun		: NVM_GEN_LUN_BITS;
  			u64 blk		: NVM_GEN_BLK_BITS;
  			u64 reserved	: NVM_GEN_RESERVED;
  		} a;
  
  		/* 1.2 device format */
  		struct {
  			u64 ch		: NVM_GEN_CH_BITS;
  			u64 lun		: NVM_GEN_LUN_BITS;
  			u64 blk		: NVM_GEN_BLK_BITS;
  			u64 pg		: NVM_12_PG_BITS;
  			u64 pl		: NVM_12_PL_BITS;
  			u64 sec		: NVM_12_SEC_BITS;
  			u64 reserved	: NVM_12_RESERVED;
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
57
  		} g;
694715137   Javier González   lightnvm: add sup...
58
59
60
61
62
63
64
65
  		/* 2.0 device format */
  		struct {
  			u64 grp		: NVM_GEN_CH_BITS;
  			u64 pu		: NVM_GEN_LUN_BITS;
  			u64 chk		: NVM_GEN_BLK_BITS;
  			u64 sec		: NVM_20_SEC_BITS;
  			u64 reserved	: NVM_20_RESERVED;
  		} m;
df414b33b   Matias Bjørling   lightnvm: add is_...
66
67
68
69
  		struct {
  			u64 line	: 63;
  			u64 is_cached	: 1;
  		} c;
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
70
71
72
73
74
75
76
  		u64 ppa;
  	};
  };
  
  struct nvm_rq;
  struct nvm_id;
  struct nvm_dev;
8e53624d4   Javier González   lightnvm: elimina...
77
  struct nvm_tgt_dev;
a294c1994   Javier González   lightnvm: impleme...
78
  struct nvm_chk_meta;
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
79

e46f4e482   Javier González   lightnvm: simplif...
80
  typedef int (nvm_id_fn)(struct nvm_dev *);
e11903f5d   Matias Bjørling   lightnvm: refacto...
81
  typedef int (nvm_op_bb_tbl_fn)(struct nvm_dev *, struct ppa_addr, u8 *);
00ee6cc3b   Matias Bjørling   lightnvm: refacto...
82
  typedef int (nvm_op_set_bb_fn)(struct nvm_dev *, struct ppa_addr *, int, int);
aff3fb18f   Matias Bjørling   lightnvm: move ba...
83
84
  typedef int (nvm_get_chk_meta_fn)(struct nvm_dev *, sector_t, int,
  							struct nvm_chk_meta *);
48e5da725   Hans Holmberg   lightnvm: move me...
85
  typedef int (nvm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *, void *);
24828d053   Igor Konopko   lightnvm: dynamic...
86
  typedef void *(nvm_create_dma_pool_fn)(struct nvm_dev *, char *, int);
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
87
88
89
90
91
92
93
  typedef void (nvm_destroy_dma_pool_fn)(void *);
  typedef void *(nvm_dev_dma_alloc_fn)(struct nvm_dev *, void *, gfp_t,
  								dma_addr_t *);
  typedef void (nvm_dev_dma_free_fn)(void *, void*, dma_addr_t);
  
  struct nvm_dev_ops {
  	nvm_id_fn		*identity;
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
94
95
  	nvm_op_bb_tbl_fn	*get_bb_tbl;
  	nvm_op_set_bb_fn	*set_bb_tbl;
a294c1994   Javier González   lightnvm: impleme...
96
  	nvm_get_chk_meta_fn	*get_chk_meta;
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
97
  	nvm_submit_io_fn	*submit_io;
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
98
99
100
101
102
  
  	nvm_create_dma_pool_fn	*create_dma_pool;
  	nvm_destroy_dma_pool_fn	*destroy_dma_pool;
  	nvm_dev_dma_alloc_fn	*dev_dma_alloc;
  	nvm_dev_dma_free_fn	*dev_dma_free;
a7fd9a4f3   Jens Axboe   lightnvm: ensure ...
103
  };
cd9e9808d   Matias Bjørling   lightnvm: Support...
104
105
106
  #ifdef CONFIG_NVM
  
  #include <linux/blkdev.h>
cd9e9808d   Matias Bjørling   lightnvm: Support...
107
108
  #include <linux/file.h>
  #include <linux/dmapool.h>
e3eb3799f   Matias Bjørling   lightnvm: core on...
109
  #include <uapi/linux/lightnvm.h>
cd9e9808d   Matias Bjørling   lightnvm: Support...
110
111
112
113
114
115
116
117
118
119
120
  
  enum {
  	/* HW Responsibilities */
  	NVM_RSP_L2P	= 1 << 0,
  	NVM_RSP_ECC	= 1 << 1,
  
  	/* Physical Adressing Mode */
  	NVM_ADDRMODE_LINEAR	= 0,
  	NVM_ADDRMODE_CHANNEL	= 1,
  
  	/* Plane programming mode for LUN */
d5bdec8dd   Matias Bjørling   lightnvm: fold ge...
121
122
123
  	NVM_PLANE_SINGLE	= 1,
  	NVM_PLANE_DOUBLE	= 2,
  	NVM_PLANE_QUAD		= 4,
cd9e9808d   Matias Bjørling   lightnvm: Support...
124
125
126
127
128
129
  
  	/* Status codes */
  	NVM_RSP_SUCCESS		= 0x0,
  	NVM_RSP_NOT_CHANGEABLE	= 0x1,
  	NVM_RSP_ERR_FAILWRITE	= 0x40ff,
  	NVM_RSP_ERR_EMPTYPAGE	= 0x42ff,
402ab9a89   Javier González   lightnvm: add ECC...
130
  	NVM_RSP_ERR_FAILECC	= 0x4281,
38ea2f765   Javier González   lightnvm: Add CRC...
131
  	NVM_RSP_ERR_FAILCRC	= 0x4004,
402ab9a89   Javier González   lightnvm: add ECC...
132
  	NVM_RSP_WARN_HIGHECC	= 0x4700,
cd9e9808d   Matias Bjørling   lightnvm: Support...
133
134
  
  	/* Device opcodes */
cd9e9808d   Matias Bjørling   lightnvm: Support...
135
136
137
138
139
140
141
142
  	NVM_OP_PWRITE		= 0x91,
  	NVM_OP_PREAD		= 0x92,
  	NVM_OP_ERASE		= 0x90,
  
  	/* PPA Command Flags */
  	NVM_IO_SNGL_ACCESS	= 0x0,
  	NVM_IO_DUAL_ACCESS	= 0x1,
  	NVM_IO_QUAD_ACCESS	= 0x2,
57b4bd06f   Matias Bjørling   lightnvm: comment...
143
  	/* NAND Access Modes */
cd9e9808d   Matias Bjørling   lightnvm: Support...
144
145
  	NVM_IO_SUSPEND		= 0x80,
  	NVM_IO_SLC_MODE		= 0x100,
a7737f39c   Javier González   lightnvm: rename ...
146
  	NVM_IO_SCRAMBLE_ENABLE	= 0x200,
57b4bd06f   Matias Bjørling   lightnvm: comment...
147
148
149
150
  
  	/* Block Types */
  	NVM_BLK_T_FREE		= 0x0,
  	NVM_BLK_T_BAD		= 0x1,
b5d4acd4c   Matias Bjørling   lightnvm: fix mis...
151
152
153
  	NVM_BLK_T_GRWN_BAD	= 0x2,
  	NVM_BLK_T_DEV		= 0x4,
  	NVM_BLK_T_HOST		= 0x8,
f9a999507   Matias Bjørling   lightnvm: add mcc...
154
155
156
157
158
159
  
  	/* Memory capabilities */
  	NVM_ID_CAP_SLC		= 0x1,
  	NVM_ID_CAP_CMD_SUSPEND	= 0x2,
  	NVM_ID_CAP_SCRAMBLE	= 0x4,
  	NVM_ID_CAP_ENCRYPT	= 0x8,
ca5927e7a   Matias Bjørling   lightnvm: introdu...
160
161
162
163
  
  	/* Memory types */
  	NVM_ID_FMTYPE_SLC	= 0,
  	NVM_ID_FMTYPE_MLC	= 1,
bf6431856   Matias Bjørling   lightnvm: allow t...
164
165
166
167
  
  	/* Device capabilities */
  	NVM_ID_DCAP_BBLKMGMT	= 0x1,
  	NVM_UD_DCAP_ECC		= 0x2,
ca5927e7a   Matias Bjørling   lightnvm: introdu...
168
169
170
171
172
173
174
175
176
177
  };
  
  struct nvm_id_lp_mlc {
  	u16	num_pairs;
  	u8	pairs[886];
  };
  
  struct nvm_id_lp_tbl {
  	__u8	id[8];
  	struct nvm_id_lp_mlc mlc;
cd9e9808d   Matias Bjørling   lightnvm: Support...
178
  };
e46f4e482   Javier González   lightnvm: simplif...
179
  struct nvm_addrf_12 {
c6ac3f35d   Matias Bjørling   lightnvm: flatten...
180
  	u8	ch_len;
c6ac3f35d   Matias Bjørling   lightnvm: flatten...
181
  	u8	lun_len;
c6ac3f35d   Matias Bjørling   lightnvm: flatten...
182
  	u8	blk_len;
c6ac3f35d   Matias Bjørling   lightnvm: flatten...
183
  	u8	pg_len;
e46f4e482   Javier González   lightnvm: simplif...
184
  	u8	pln_len;
a40afad90   Javier González   lightnvm: normali...
185
  	u8	sec_len;
c6ac3f35d   Matias Bjørling   lightnvm: flatten...
186

e46f4e482   Javier González   lightnvm: simplif...
187
188
189
190
191
  	u8	ch_offset;
  	u8	lun_offset;
  	u8	blk_offset;
  	u8	pg_offset;
  	u8	pln_offset;
a40afad90   Javier González   lightnvm: normali...
192
  	u8	sec_offset;
fae7fae40   Matias Bjørling   lightnvm: make ge...
193

e46f4e482   Javier González   lightnvm: simplif...
194
195
196
197
198
199
200
  	u64	ch_mask;
  	u64	lun_mask;
  	u64	blk_mask;
  	u64	pg_mask;
  	u64	pln_mask;
  	u64	sec_mask;
  };
62771fe0a   Matias Bjørling   lightnvm: add 2.0...
201

e46f4e482   Javier González   lightnvm: simplif...
202
203
204
205
206
207
  struct nvm_addrf {
  	u8	ch_len;
  	u8	lun_len;
  	u8	chk_len;
  	u8	sec_len;
  	u8	rsv_len[2];
c6ac3f35d   Matias Bjørling   lightnvm: flatten...
208

e46f4e482   Javier González   lightnvm: simplif...
209
210
211
212
213
214
215
216
217
218
219
220
  	u8	ch_offset;
  	u8	lun_offset;
  	u8	chk_offset;
  	u8	sec_offset;
  	u8	rsv_off[2];
  
  	u64	ch_mask;
  	u64	lun_mask;
  	u64	chk_mask;
  	u64	sec_mask;
  	u64	rsv_mask[2];
  };
cd9e9808d   Matias Bjørling   lightnvm: Support...
221

32ef9412c   Javier González   lightnvm: pblk: i...
222
223
224
225
226
227
228
229
230
231
232
233
  enum {
  	/* Chunk states */
  	NVM_CHK_ST_FREE =	1 << 0,
  	NVM_CHK_ST_CLOSED =	1 << 1,
  	NVM_CHK_ST_OPEN =	1 << 2,
  	NVM_CHK_ST_OFFLINE =	1 << 3,
  
  	/* Chunk types */
  	NVM_CHK_TP_W_SEQ =	1 << 0,
  	NVM_CHK_TP_W_RAN =	1 << 1,
  	NVM_CHK_TP_SZ_SPEC =	1 << 4,
  };
a294c1994   Javier González   lightnvm: impleme...
234
235
236
237
238
239
240
241
242
243
244
245
246
  /*
   * Note: The structure size is linked to nvme_nvm_chk_meta such that the same
   * buffer can be used when converting from little endian to cpu addressing.
   */
  struct nvm_chk_meta {
  	u8	state;
  	u8	type;
  	u8	wi;
  	u8	rsvd[5];
  	u64	slba;
  	u64	cnlb;
  	u64	wp;
  };
cd9e9808d   Matias Bjørling   lightnvm: Support...
247
248
  struct nvm_target {
  	struct list_head list;
8e79b5cb1   Javier González   lightnvm: move bl...
249
  	struct nvm_tgt_dev *dev;
cd9e9808d   Matias Bjørling   lightnvm: Support...
250
251
252
  	struct nvm_tgt_type *type;
  	struct gendisk *disk;
  };
cd9e9808d   Matias Bjørling   lightnvm: Support...
253
  #define ADDR_EMPTY (~0ULL)
e53927393   Javier González   lightnvm: set tar...
254
255
256
  #define NVM_TARGET_DEFAULT_OP (101)
  #define NVM_TARGET_MIN_OP (3)
  #define NVM_TARGET_MAX_OP (80)
cd9e9808d   Matias Bjørling   lightnvm: Support...
257
258
259
  #define NVM_VERSION_MAJOR 1
  #define NVM_VERSION_MINOR 0
  #define NVM_VERSION_PATCH 0
89a09c564   Matias Bjørling   lightnvm: remove ...
260
  #define NVM_MAX_VLBA (64) /* max logical blocks in a vector command */
91276162d   Matias Bjørling   lightnvm: refacto...
261
  struct nvm_rq;
72d256ecc   Matias Bjørling   lightnvm: move rq...
262
  typedef void (nvm_end_io_fn)(struct nvm_rq *);
91276162d   Matias Bjørling   lightnvm: refacto...
263

cd9e9808d   Matias Bjørling   lightnvm: Support...
264
  struct nvm_rq {
8e53624d4   Javier González   lightnvm: elimina...
265
  	struct nvm_tgt_dev *dev;
cd9e9808d   Matias Bjørling   lightnvm: Support...
266
267
268
269
270
271
272
273
274
  
  	struct bio *bio;
  
  	union {
  		struct ppa_addr ppa_addr;
  		dma_addr_t dma_ppa_list;
  	};
  
  	struct ppa_addr *ppa_list;
003fad376   Javier González   lightnvm: enable ...
275
276
  	void *meta_list;
  	dma_addr_t dma_meta_list;
cd9e9808d   Matias Bjørling   lightnvm: Support...
277

91276162d   Matias Bjørling   lightnvm: refacto...
278
  	nvm_end_io_fn *end_io;
cd9e9808d   Matias Bjørling   lightnvm: Support...
279
  	uint8_t opcode;
6d5be9590   Javier González   lightnvm: rename ...
280
  	uint16_t nr_ppas;
cd9e9808d   Matias Bjørling   lightnvm: Support...
281
  	uint16_t flags;
72d256ecc   Matias Bjørling   lightnvm: move rq...
282

9f8672684   Matias Bjorling   nvme: lightnvm: r...
283
  	u64 ppa_status; /* ppa media status */
72d256ecc   Matias Bjørling   lightnvm: move rq...
284
  	int error;
06894efea   Matias Bjørling   lightnvm: use end...
285

d7b680167   Matias Bjørling   lightnvm: combine...
286
  	int is_seq; /* Sequential hint flag. 1.2 only */
06894efea   Matias Bjørling   lightnvm: use end...
287
  	void *private;
cd9e9808d   Matias Bjørling   lightnvm: Support...
288
289
290
291
292
293
294
295
296
297
298
  };
  
  static inline struct nvm_rq *nvm_rq_from_pdu(void *pdu)
  {
  	return pdu - sizeof(struct nvm_rq);
  }
  
  static inline void *nvm_rq_to_pdu(struct nvm_rq *rqdata)
  {
  	return rqdata + 1;
  }
d68a93440   Hans Holmberg   lightnvm: introdu...
299
300
301
302
  static inline struct ppa_addr *nvm_rq_to_ppa_list(struct nvm_rq *rqd)
  {
  	return (rqd->nr_ppas > 1) ? rqd->ppa_list : &rqd->ppa_addr;
  }
ff0e498bf   Javier González   lightnvm: manage ...
303
304
  enum {
  	NVM_BLK_ST_FREE =	0x1,	/* Free block */
077d23899   Matias Bjørling   lightnvm: remove ...
305
  	NVM_BLK_ST_TGT =	0x2,	/* Block in use by target */
ff0e498bf   Javier González   lightnvm: manage ...
306
  	NVM_BLK_ST_BAD =	0x8,	/* Bad block */
cd9e9808d   Matias Bjørling   lightnvm: Support...
307
  };
e46f4e482   Javier González   lightnvm: simplif...
308
  /* Instance geometry */
8e79b5cb1   Javier González   lightnvm: move bl...
309
  struct nvm_geo {
e46f4e482   Javier González   lightnvm: simplif...
310
  	/* device reported version */
3cb98f84d   Javier González   lightnvm: add min...
311
312
  	u8	major_ver_id;
  	u8	minor_ver_id;
e46f4e482   Javier González   lightnvm: simplif...
313

f1d4e8121   Javier González   lightnvm: add sho...
314
315
  	/* kernel short version */
  	u8	version;
e46f4e482   Javier González   lightnvm: simplif...
316
  	/* instance specific geometry */
a40afad90   Javier González   lightnvm: normali...
317
318
  	int num_ch;
  	int num_lun;		/* per channel */
fae7fae40   Matias Bjørling   lightnvm: make ge...
319

e46f4e482   Javier González   lightnvm: simplif...
320
321
322
323
324
325
326
327
328
  	/* calculated values */
  	int all_luns;		/* across channels */
  	int all_chunks;		/* across channels */
  
  	int op;			/* over-provision in instance */
  
  	sector_t total_secs;	/* across channels */
  
  	/* chunk geometry */
a40afad90   Javier González   lightnvm: normali...
329
  	u32	num_chk;	/* chunks per lun */
e46f4e482   Javier González   lightnvm: simplif...
330
331
332
  	u32	clba;		/* sectors per chunk */
  	u16	csecs;		/* sector size */
  	u16	sos;		/* out-of-band area size */
a16816b9e   Igor Konopko   lightnvm: disable...
333
  	bool	ext;		/* metadata in extended data buffer */
a14669ebc   Igor Konopko   lightnvm: Inherit...
334
  	u32	mdts;		/* Max data transfer size*/
cd9e9808d   Matias Bjørling   lightnvm: Support...
335

e46f4e482   Javier González   lightnvm: simplif...
336
337
338
339
  	/* device write constrains */
  	u32	ws_min;		/* minimum write size */
  	u32	ws_opt;		/* optimal write size */
  	u32	mw_cunits;	/* distance required for successful read */
3f48021ba   Javier González   lightnvm: complet...
340
341
  	u32	maxoc;		/* maximum open chunks */
  	u32	maxocpu;	/* maximum open chunks per parallel unit */
fae7fae40   Matias Bjørling   lightnvm: make ge...
342

e46f4e482   Javier González   lightnvm: simplif...
343
344
  	/* device capabilities */
  	u32	mccap;
fae7fae40   Matias Bjørling   lightnvm: make ge...
345

e46f4e482   Javier González   lightnvm: simplif...
346
347
348
349
350
351
352
  	/* device timings */
  	u32	trdt;		/* Avg. Tread (ns) */
  	u32	trdm;		/* Max Tread (ns) */
  	u32	tprt;		/* Avg. Tprog (ns) */
  	u32	tprm;		/* Max Tprog (ns) */
  	u32	tbet;		/* Avg. Terase (ns) */
  	u32	tbem;		/* Max Terase (ns) */
e53927393   Javier González   lightnvm: set tar...
353

e46f4e482   Javier González   lightnvm: simplif...
354
355
  	/* generic address format */
  	struct nvm_addrf addrf;
fae7fae40   Matias Bjørling   lightnvm: make ge...
356

e46f4e482   Javier González   lightnvm: simplif...
357
358
359
360
361
362
363
364
365
366
367
368
  	/* 1.2 compatibility */
  	u8	vmnt;
  	u32	cap;
  	u32	dom;
  
  	u8	mtype;
  	u8	fmtype;
  
  	u16	cpar;
  	u32	mpos;
  
  	u8	num_pln;
a40afad90   Javier González   lightnvm: normali...
369
  	u8	pln_mode;
e46f4e482   Javier González   lightnvm: simplif...
370
371
  	u16	num_pg;
  	u16	fpg_sz;
8e79b5cb1   Javier González   lightnvm: move bl...
372
  };
ade69e243   Matias Bjørling   lightnvm: merge g...
373
  /* sub-device structure */
8e79b5cb1   Javier González   lightnvm: move bl...
374
375
376
  struct nvm_tgt_dev {
  	/* Device information */
  	struct nvm_geo geo;
8e53624d4   Javier González   lightnvm: elimina...
377
378
  	/* Base ppas for target LUNs */
  	struct ppa_addr *luns;
8e79b5cb1   Javier González   lightnvm: move bl...
379
  	struct request_queue *q;
959e911b3   Javier González   lightnvm: introdu...
380
  	struct nvm_dev *parent;
8e53624d4   Javier González   lightnvm: elimina...
381
  	void *map;
8e79b5cb1   Javier González   lightnvm: move bl...
382
383
384
385
386
387
  };
  
  struct nvm_dev {
  	struct nvm_dev_ops *ops;
  
  	struct list_head devices;
8e79b5cb1   Javier González   lightnvm: move bl...
388
389
  	/* Device information */
  	struct nvm_geo geo;
cd9e9808d   Matias Bjørling   lightnvm: Support...
390

da1e28491   Wenwei Tao   lightnvm: add a b...
391
  	unsigned long *lun_map;
75b856493   Javier González   lightnvm: rename ...
392
  	void *dma_pool;
cd9e9808d   Matias Bjørling   lightnvm: Support...
393

cd9e9808d   Matias Bjørling   lightnvm: Support...
394
395
396
  	/* Backend device */
  	struct request_queue *q;
  	char name[DISK_NAME_LEN];
40267efdd   Simon A. F. Lund   lightnvm: expose ...
397
  	void *private_data;
e3eb3799f   Matias Bjørling   lightnvm: core on...
398

e69397ea0   Igor Konopko   lightnvm: track i...
399
  	struct kref ref;
8e53624d4   Javier González   lightnvm: elimina...
400
  	void *rmap;
e3eb3799f   Matias Bjørling   lightnvm: core on...
401
  	struct mutex mlock;
4c9dacb82   Wenwei Tao   lightnvm: specify...
402
  	spinlock_t lock;
ade69e243   Matias Bjørling   lightnvm: merge g...
403
404
405
406
  
  	/* target management */
  	struct list_head area_list;
  	struct list_head targets;
cd9e9808d   Matias Bjørling   lightnvm: Support...
407
  };
7100d50a7   Javier González   lightnvm: make ad...
408
  static inline struct ppa_addr generic_to_dev_addr(struct nvm_dev *dev,
dab8ee9e8   Matias Bjørling   lightnvm: cleanup...
409
  						  struct ppa_addr r)
cd9e9808d   Matias Bjørling   lightnvm: Support...
410
  {
7100d50a7   Javier González   lightnvm: make ad...
411
  	struct nvm_geo *geo = &dev->geo;
cd9e9808d   Matias Bjørling   lightnvm: Support...
412
  	struct ppa_addr l;
694715137   Javier González   lightnvm: add sup...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
  	if (geo->version == NVM_OCSSD_SPEC_12) {
  		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf;
  
  		l.ppa = ((u64)r.g.ch) << ppaf->ch_offset;
  		l.ppa |= ((u64)r.g.lun) << ppaf->lun_offset;
  		l.ppa |= ((u64)r.g.blk) << ppaf->blk_offset;
  		l.ppa |= ((u64)r.g.pg) << ppaf->pg_offset;
  		l.ppa |= ((u64)r.g.pl) << ppaf->pln_offset;
  		l.ppa |= ((u64)r.g.sec) << ppaf->sec_offset;
  	} else {
  		struct nvm_addrf *lbaf = &geo->addrf;
  
  		l.ppa = ((u64)r.m.grp) << lbaf->ch_offset;
  		l.ppa |= ((u64)r.m.pu) << lbaf->lun_offset;
  		l.ppa |= ((u64)r.m.chk) << lbaf->chk_offset;
  		l.ppa |= ((u64)r.m.sec) << lbaf->sec_offset;
  	}
cd9e9808d   Matias Bjørling   lightnvm: Support...
430
431
432
  
  	return l;
  }
7100d50a7   Javier González   lightnvm: make ad...
433
  static inline struct ppa_addr dev_to_generic_addr(struct nvm_dev *dev,
dab8ee9e8   Matias Bjørling   lightnvm: cleanup...
434
  						  struct ppa_addr r)
cd9e9808d   Matias Bjørling   lightnvm: Support...
435
  {
7100d50a7   Javier González   lightnvm: make ad...
436
  	struct nvm_geo *geo = &dev->geo;
cd9e9808d   Matias Bjørling   lightnvm: Support...
437
  	struct ppa_addr l;
5389a1dfb   Javier González   lightnvm: initial...
438
  	l.ppa = 0;
e46f4e482   Javier González   lightnvm: simplif...
439

694715137   Javier González   lightnvm: add sup...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
  	if (geo->version == NVM_OCSSD_SPEC_12) {
  		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)&geo->addrf;
  
  		l.g.ch = (r.ppa & ppaf->ch_mask) >> ppaf->ch_offset;
  		l.g.lun = (r.ppa & ppaf->lun_mask) >> ppaf->lun_offset;
  		l.g.blk = (r.ppa & ppaf->blk_mask) >> ppaf->blk_offset;
  		l.g.pg = (r.ppa & ppaf->pg_mask) >> ppaf->pg_offset;
  		l.g.pl = (r.ppa & ppaf->pln_mask) >> ppaf->pln_offset;
  		l.g.sec = (r.ppa & ppaf->sec_mask) >> ppaf->sec_offset;
  	} else {
  		struct nvm_addrf *lbaf = &geo->addrf;
  
  		l.m.grp = (r.ppa & lbaf->ch_mask) >> lbaf->ch_offset;
  		l.m.pu = (r.ppa & lbaf->lun_mask) >> lbaf->lun_offset;
  		l.m.chk = (r.ppa & lbaf->chk_mask) >> lbaf->chk_offset;
  		l.m.sec = (r.ppa & lbaf->sec_mask) >> lbaf->sec_offset;
  	}
cd9e9808d   Matias Bjørling   lightnvm: Support...
457
458
459
  
  	return l;
  }
2cf99bbd1   Javier González   lightnvm: pblk: a...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  static inline u64 dev_to_chunk_addr(struct nvm_dev *dev, void *addrf,
  				    struct ppa_addr p)
  {
  	struct nvm_geo *geo = &dev->geo;
  	u64 caddr;
  
  	if (geo->version == NVM_OCSSD_SPEC_12) {
  		struct nvm_addrf_12 *ppaf = (struct nvm_addrf_12 *)addrf;
  
  		caddr = (u64)p.g.pg << ppaf->pg_offset;
  		caddr |= (u64)p.g.pl << ppaf->pln_offset;
  		caddr |= (u64)p.g.sec << ppaf->sec_offset;
  	} else {
  		caddr = p.m.sec;
  	}
  
  	return caddr;
  }
7f985f9a6   Javier González   lightnvm: move pp...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
  static inline struct ppa_addr nvm_ppa32_to_ppa64(struct nvm_dev *dev,
  						 void *addrf, u32 ppa32)
  {
  	struct ppa_addr ppa64;
  
  	ppa64.ppa = 0;
  
  	if (ppa32 == -1) {
  		ppa64.ppa = ADDR_EMPTY;
  	} else if (ppa32 & (1U << 31)) {
  		ppa64.c.line = ppa32 & ((~0U) >> 1);
  		ppa64.c.is_cached = 1;
  	} else {
  		struct nvm_geo *geo = &dev->geo;
  
  		if (geo->version == NVM_OCSSD_SPEC_12) {
  			struct nvm_addrf_12 *ppaf = addrf;
  
  			ppa64.g.ch = (ppa32 & ppaf->ch_mask) >>
  							ppaf->ch_offset;
  			ppa64.g.lun = (ppa32 & ppaf->lun_mask) >>
  							ppaf->lun_offset;
  			ppa64.g.blk = (ppa32 & ppaf->blk_mask) >>
  							ppaf->blk_offset;
  			ppa64.g.pg = (ppa32 & ppaf->pg_mask) >>
  							ppaf->pg_offset;
  			ppa64.g.pl = (ppa32 & ppaf->pln_mask) >>
  							ppaf->pln_offset;
  			ppa64.g.sec = (ppa32 & ppaf->sec_mask) >>
  							ppaf->sec_offset;
  		} else {
  			struct nvm_addrf *lbaf = addrf;
  
  			ppa64.m.grp = (ppa32 & lbaf->ch_mask) >>
  							lbaf->ch_offset;
  			ppa64.m.pu = (ppa32 & lbaf->lun_mask) >>
  							lbaf->lun_offset;
  			ppa64.m.chk = (ppa32 & lbaf->chk_mask) >>
  							lbaf->chk_offset;
  			ppa64.m.sec = (ppa32 & lbaf->sec_mask) >>
  							lbaf->sec_offset;
  		}
  	}
  
  	return ppa64;
  }
  
  static inline u32 nvm_ppa64_to_ppa32(struct nvm_dev *dev,
  				     void *addrf, struct ppa_addr ppa64)
  {
  	u32 ppa32 = 0;
  
  	if (ppa64.ppa == ADDR_EMPTY) {
  		ppa32 = ~0U;
  	} else if (ppa64.c.is_cached) {
  		ppa32 |= ppa64.c.line;
  		ppa32 |= 1U << 31;
  	} else {
  		struct nvm_geo *geo = &dev->geo;
  
  		if (geo->version == NVM_OCSSD_SPEC_12) {
  			struct nvm_addrf_12 *ppaf = addrf;
  
  			ppa32 |= ppa64.g.ch << ppaf->ch_offset;
  			ppa32 |= ppa64.g.lun << ppaf->lun_offset;
  			ppa32 |= ppa64.g.blk << ppaf->blk_offset;
  			ppa32 |= ppa64.g.pg << ppaf->pg_offset;
  			ppa32 |= ppa64.g.pl << ppaf->pln_offset;
  			ppa32 |= ppa64.g.sec << ppaf->sec_offset;
  		} else {
  			struct nvm_addrf *lbaf = addrf;
  
  			ppa32 |= ppa64.m.grp << lbaf->ch_offset;
  			ppa32 |= ppa64.m.pu << lbaf->lun_offset;
  			ppa32 |= ppa64.m.chk << lbaf->chk_offset;
  			ppa32 |= ppa64.m.sec << lbaf->sec_offset;
  		}
  	}
  
  	return ppa32;
  }
bf82fa2f5   Hans Holmberg   lightnvm: pblk: f...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  static inline int nvm_next_ppa_in_chk(struct nvm_tgt_dev *dev,
  				      struct ppa_addr *ppa)
  {
  	struct nvm_geo *geo = &dev->geo;
  	int last = 0;
  
  	if (geo->version == NVM_OCSSD_SPEC_12) {
  		int sec = ppa->g.sec;
  
  		sec++;
  		if (sec == geo->ws_min) {
  			int pg = ppa->g.pg;
  
  			sec = 0;
  			pg++;
  			if (pg == geo->num_pg) {
  				int pl = ppa->g.pl;
  
  				pg = 0;
  				pl++;
  				if (pl == geo->num_pln)
  					last = 1;
  
  				ppa->g.pl = pl;
  			}
  			ppa->g.pg = pg;
  		}
  		ppa->g.sec = sec;
  	} else {
  		ppa->m.sec++;
  		if (ppa->m.sec == geo->clba)
  			last = 1;
  	}
  
  	return last;
  }
7f985f9a6   Javier González   lightnvm: move pp...
595

cd9e9808d   Matias Bjørling   lightnvm: Support...
596
  typedef sector_t (nvm_tgt_capacity_fn)(void *);
4af3f75d7   Javier González   lightnvm: allow t...
597
598
  typedef void *(nvm_tgt_init_fn)(struct nvm_tgt_dev *, struct gendisk *,
  				int flags);
a7c9e9109   Javier González   lightnvm: pass fl...
599
  typedef void (nvm_tgt_exit_fn)(void *, bool);
9a69b0ed6   Javier González   lightnvm: allow t...
600
601
  typedef int (nvm_tgt_sysfs_init_fn)(struct gendisk *);
  typedef void (nvm_tgt_sysfs_exit_fn)(struct gendisk *);
cd9e9808d   Matias Bjørling   lightnvm: Support...
602

656e33ca3   Matias Bjørling   lightnvm: move de...
603
604
605
606
  enum {
  	NVM_TGT_F_DEV_L2P = 0,
  	NVM_TGT_F_HOST_L2P = 1 << 0,
  };
cd9e9808d   Matias Bjørling   lightnvm: Support...
607
608
609
  struct nvm_tgt_type {
  	const char *name;
  	unsigned int version[3];
656e33ca3   Matias Bjørling   lightnvm: move de...
610
  	int flags;
cd9e9808d   Matias Bjørling   lightnvm: Support...
611
612
  
  	/* target entry points */
c62b37d96   Christoph Hellwig   block: move ->mak...
613
  	const struct block_device_operations *bops;
cd9e9808d   Matias Bjørling   lightnvm: Support...
614
  	nvm_tgt_capacity_fn *capacity;
cd9e9808d   Matias Bjørling   lightnvm: Support...
615
616
617
618
  
  	/* module-specific init/teardown */
  	nvm_tgt_init_fn *init;
  	nvm_tgt_exit_fn *exit;
9a69b0ed6   Javier González   lightnvm: allow t...
619
620
621
  	/* sysfs */
  	nvm_tgt_sysfs_init_fn *sysfs_init;
  	nvm_tgt_sysfs_exit_fn *sysfs_exit;
cd9e9808d   Matias Bjørling   lightnvm: Support...
622
623
  	/* For internal use */
  	struct list_head list;
900148296   Rakesh Pandit   lightnvm: prevent...
624
  	struct module *owner;
cd9e9808d   Matias Bjørling   lightnvm: Support...
625
  };
6063fe399   Simon A. F. Lund   lightnvm: rename ...
626
627
  extern int nvm_register_tgt_type(struct nvm_tgt_type *);
  extern void nvm_unregister_tgt_type(struct nvm_tgt_type *);
cd9e9808d   Matias Bjørling   lightnvm: Support...
628
629
630
  
  extern void *nvm_dev_dma_alloc(struct nvm_dev *, gfp_t, dma_addr_t *);
  extern void nvm_dev_dma_free(struct nvm_dev *, void *, dma_addr_t);
b0b4e09c1   Matias Bjørling   lightnvm: control...
631
632
633
  extern struct nvm_dev *nvm_alloc_dev(int);
  extern int nvm_register(struct nvm_dev *);
  extern void nvm_unregister(struct nvm_dev *);
cd9e9808d   Matias Bjørling   lightnvm: Support...
634

aff3fb18f   Matias Bjørling   lightnvm: move ba...
635
636
637
  extern int nvm_get_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr,
  			      int, struct nvm_chk_meta *);
  extern int nvm_set_chunk_meta(struct nvm_tgt_dev *, struct ppa_addr *,
333ba053d   Javier González   lightnvm: transfo...
638
  			      int, int);
48e5da725   Hans Holmberg   lightnvm: move me...
639
640
  extern int nvm_submit_io(struct nvm_tgt_dev *, struct nvm_rq *, void *);
  extern int nvm_submit_io_sync(struct nvm_tgt_dev *, struct nvm_rq *, void *);
06894efea   Matias Bjørling   lightnvm: use end...
641
  extern void nvm_end_io(struct nvm_rq *);
e3eb3799f   Matias Bjørling   lightnvm: core on...
642

cd9e9808d   Matias Bjørling   lightnvm: Support...
643
644
  #else /* CONFIG_NVM */
  struct nvm_dev_ops;
b0b4e09c1   Matias Bjørling   lightnvm: control...
645
646
647
648
649
  static inline struct nvm_dev *nvm_alloc_dev(int node)
  {
  	return ERR_PTR(-EINVAL);
  }
  static inline int nvm_register(struct nvm_dev *dev)
cd9e9808d   Matias Bjørling   lightnvm: Support...
650
651
652
  {
  	return -EINVAL;
  }
b0b4e09c1   Matias Bjørling   lightnvm: control...
653
  static inline void nvm_unregister(struct nvm_dev *dev) {}
cd9e9808d   Matias Bjørling   lightnvm: Support...
654
655
  #endif /* CONFIG_NVM */
  #endif /* LIGHTNVM.H */