Blame view

include/linux/libnvdimm.h 10.3 KB
5b497af42   Thomas Gleixner   treewide: Replace...
1
  /* SPDX-License-Identifier: GPL-2.0-only */
b94d5230d   Dan Williams   libnvdimm, nfit: ...
2
3
4
5
  /*
   * libnvdimm - Non-volatile-memory Devices Subsystem
   *
   * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
b94d5230d   Dan Williams   libnvdimm, nfit: ...
6
7
8
   */
  #ifndef __LIBNVDIMM_H__
  #define __LIBNVDIMM_H__
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
9
  #include <linux/kernel.h>
62232e45f   Dan Williams   libnvdimm: contro...
10
11
  #include <linux/sizes.h>
  #include <linux/types.h>
faec6f8a1   Dan Williams   libnvdimm, label:...
12
  #include <linux/uuid.h>
aa9ad44a4   Dave Jiang   libnvdimm: move p...
13
  #include <linux/spinlock.h>
c5d4355d1   Pankaj Gupta   libnvdimm: nd_reg...
14
  #include <linux/bio.h>
aa9ad44a4   Dave Jiang   libnvdimm: move p...
15
16
17
18
19
20
21
22
23
24
25
  
  struct badrange_entry {
  	u64 start;
  	u64 length;
  	struct list_head list;
  };
  
  struct badrange {
  	struct list_head list;
  	spinlock_t lock;
  };
e6dfb2de4   Dan Williams   libnvdimm, nfit: ...
26
27
28
  
  enum {
  	/* when a dimm supports both PMEM and BLK access a label is required */
8f078b38d   Dan Williams   libnvdimm: conver...
29
  	NDD_ALIASING = 0,
581388209   Dan Williams   libnvdimm, nfit: ...
30
  	/* unarmed memory devices may not persist writes */
8f078b38d   Dan Williams   libnvdimm: conver...
31
32
33
  	NDD_UNARMED = 1,
  	/* locked memory devices should not be accessed */
  	NDD_LOCKED = 2,
7d988097c   Dave Jiang   acpi/nfit, libnvd...
34
35
36
37
  	/* memory under security wipes should not be accessed */
  	NDD_SECURITY_OVERWRITE = 3,
  	/*  tracking whether or not there is a pending device reference */
  	NDD_WORK_PENDING = 4,
d5d30d5a5   Dan Williams   libnvdimm/dimm: A...
38
39
  	/* ignore / filter NSLABEL_FLAG_LOCAL for this DIMM, i.e. no aliasing */
  	NDD_NOBLK = 5,
a0e374525   Dan Williams   libnvdimm/region:...
40
41
  	/* dimm supports namespace labels */
  	NDD_LABELING = 6,
62232e45f   Dan Williams   libnvdimm: contro...
42
43
44
  
  	/* need to set a limit somewhere, but yes, this is likely overkill */
  	ND_IOCTL_MAX_BUFLEN = SZ_4M,
4577b0665   Dan Williams   nfit: update addr...
45
  	ND_CMD_MAX_ELEM = 5,
40abf9be8   Jerry Hoemann   libnvdimm: increa...
46
  	ND_CMD_MAX_ENVELOPE = 256,
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
47
  	ND_MAX_MAPPINGS = 32,
1b40e09a1   Dan Williams   libnvdimm: blk la...
48

004f1afbe   Dan Williams   libnvdimm, pmem: ...
49
50
  	/* region flag indicating to direct-map persistent memory by default */
  	ND_REGION_PAGEMAP = 0,
06e8ccdab   Dave Jiang   acpi: nfit: Add s...
51
52
53
54
55
  	/*
  	 * Platform ensures entire CPU store data path is flushed to pmem on
  	 * system power loss.
  	 */
  	ND_REGION_PERSIST_CACHE = 1,
30e6d7bf2   Dave Jiang   acpi: nfit: add p...
56
57
58
59
60
61
  	/*
  	 * Platform provides mechanisms to automatically flush outstanding
  	 * write data from memory controler to pmem on system power loss.
  	 * (ADR)
  	 */
  	ND_REGION_PERSIST_MEMCTRL = 2,
004f1afbe   Dan Williams   libnvdimm, pmem: ...
62

c5d4355d1   Pankaj Gupta   libnvdimm: nd_reg...
63
64
  	/* Platform provides asynchronous flush mechanism */
  	ND_REGION_ASYNC = 3,
1b40e09a1   Dan Williams   libnvdimm: blk la...
65
66
  	/* mark newly adjusted resources as requiring a label update */
  	DPA_RESOURCE_ADJUSTED = 1 << 0,
e6dfb2de4   Dan Williams   libnvdimm, nfit: ...
67
  };
b94d5230d   Dan Williams   libnvdimm, nfit: ...
68
69
70
71
  struct nvdimm;
  struct nvdimm_bus_descriptor;
  typedef int (*ndctl_fn)(struct nvdimm_bus_descriptor *nd_desc,
  		struct nvdimm *nvdimm, unsigned int cmd, void *buf,
aef253382   Dan Williams   libnvdimm, nfit: ...
72
  		unsigned int buf_len, int *cmd_rc);
b94d5230d   Dan Williams   libnvdimm, nfit: ...
73

1ff19f487   Oliver O'Halloran   libnvdimm: Add of...
74
  struct device_node;
b94d5230d   Dan Williams   libnvdimm, nfit: ...
75
  struct nvdimm_bus_descriptor {
45def22c1   Dan Williams   libnvdimm: contro...
76
  	const struct attribute_group **attr_groups;
e3654eca7   Dan Williams   nfit, libnvdimm: ...
77
  	unsigned long cmd_mask;
92fe2aa85   Dan Williams   libnvdimm: Valida...
78
79
  	unsigned long dimm_family_mask;
  	unsigned long bus_family_mask;
bc9775d86   Dan Williams   libnvdimm: move -...
80
  	struct module *module;
b94d5230d   Dan Williams   libnvdimm, nfit: ...
81
  	char *provider_name;
1ff19f487   Oliver O'Halloran   libnvdimm: Add of...
82
  	struct device_node *of_node;
b94d5230d   Dan Williams   libnvdimm, nfit: ...
83
  	ndctl_fn ndctl;
7ae0fa439   Dan Williams   nfit, libnvdimm: ...
84
  	int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);
87bf572e1   Dan Williams   nfit: disable use...
85
  	int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc,
b3ed2ce02   Dave Jiang   acpi/nfit: Add su...
86
  			struct nvdimm *nvdimm, unsigned int cmd, void *data);
48001ea50   Dan Williams   PM, libnvdimm: Ad...
87
  	const struct nvdimm_bus_fw_ops *fw_ops;
b94d5230d   Dan Williams   libnvdimm, nfit: ...
88
  };
62232e45f   Dan Williams   libnvdimm: contro...
89
90
91
92
93
94
  struct nd_cmd_desc {
  	int in_num;
  	int out_num;
  	u32 in_sizes[ND_CMD_MAX_ELEM];
  	int out_sizes[ND_CMD_MAX_ELEM];
  };
eaf961536   Dan Williams   libnvdimm, nfit: ...
95
  struct nd_interleave_set {
c12c48ce8   Dan Williams   libnvdimm, label:...
96
97
98
99
  	/* v1.1 definition of the interleave-set-cookie algorithm */
  	u64 cookie1;
  	/* v1.2 definition of the interleave-set-cookie algorithm */
  	u64 cookie2;
86ef58a4e   Dan Williams   nfit, libnvdimm: ...
100
101
  	/* compatibility with initial buggy Linux implementation */
  	u64 altcookie;
faec6f8a1   Dan Williams   libnvdimm, label:...
102
103
  
  	guid_t type_guid;
eaf961536   Dan Williams   libnvdimm, nfit: ...
104
  };
44c462eb9   Dan Williams   libnvdimm, region...
105
106
107
108
  struct nd_mapping_desc {
  	struct nvdimm *nvdimm;
  	u64 start;
  	u64 size;
401c0a19c   Dan Williams   nfit, libnvdimm, ...
109
  	int position;
44c462eb9   Dan Williams   libnvdimm, region...
110
  };
c5d4355d1   Pankaj Gupta   libnvdimm: nd_reg...
111
  struct nd_region;
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
112
113
  struct nd_region_desc {
  	struct resource *res;
44c462eb9   Dan Williams   libnvdimm, region...
114
  	struct nd_mapping_desc *mapping;
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
115
116
  	u16 num_mappings;
  	const struct attribute_group **attr_groups;
eaf961536   Dan Williams   libnvdimm, nfit: ...
117
  	struct nd_interleave_set *nd_set;
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
118
  	void *provider_data;
5212e11fd   Vishal Verma   nd_btt: atomic se...
119
  	int num_lanes;
41d7a6d63   Toshi Kani   libnvdimm: Set nu...
120
  	int numa_node;
8fc5c7355   Dan Williams   acpi/nfit, device...
121
  	int target_node;
004f1afbe   Dan Williams   libnvdimm, pmem: ...
122
  	unsigned long flags;
1ff19f487   Oliver O'Halloran   libnvdimm: Add of...
123
  	struct device_node *of_node;
c5d4355d1   Pankaj Gupta   libnvdimm: nd_reg...
124
  	int (*flush)(struct nd_region *nd_region, struct bio *bio);
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
125
  };
29b9aa0aa   Dan Williams   libnvdimm: introd...
126
127
128
129
130
131
132
133
  struct device;
  void *devm_nvdimm_memremap(struct device *dev, resource_size_t offset,
  		size_t size, unsigned long flags);
  static inline void __iomem *devm_nvdimm_ioremap(struct device *dev,
  		resource_size_t offset, size_t size)
  {
  	return (void __iomem *) devm_nvdimm_memremap(dev, offset, size, 0);
  }
62232e45f   Dan Williams   libnvdimm: contro...
134
  struct nvdimm_bus;
3d88002e4   Dan Williams   libnvdimm: suppor...
135
  struct module;
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
136
137
138
139
  struct device;
  struct nd_blk_region;
  struct nd_blk_region_desc {
  	int (*enable)(struct nvdimm_bus *nvdimm_bus, struct device *dev);
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
140
141
142
143
144
145
146
147
148
149
150
  	int (*do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
  			void *iobuf, u64 len, int rw);
  	struct nd_region_desc ndr_desc;
  };
  
  static inline struct nd_blk_region_desc *to_blk_region_desc(
  		struct nd_region_desc *ndr_desc)
  {
  	return container_of(ndr_desc, struct nd_blk_region_desc, ndr_desc);
  
  }
d78c620a2   Dan Williams   libnvdimm/securit...
151
152
153
154
155
  /*
   * Note that separate bits for locked + unlocked are defined so that
   * 'flags == 0' corresponds to an error / not-supported state.
   */
  enum nvdimm_security_bits {
f29893965   Dave Jiang   acpi/nfit, libnvd...
156
157
158
159
160
161
  	NVDIMM_SECURITY_DISABLED,
  	NVDIMM_SECURITY_UNLOCKED,
  	NVDIMM_SECURITY_LOCKED,
  	NVDIMM_SECURITY_FROZEN,
  	NVDIMM_SECURITY_OVERWRITE,
  };
4c6926a23   Dave Jiang   acpi/nfit, libnvd...
162
163
164
165
166
167
  #define NVDIMM_PASSPHRASE_LEN		32
  #define NVDIMM_KEY_DESC_LEN		22
  
  struct nvdimm_key_data {
  	u8 data[NVDIMM_PASSPHRASE_LEN];
  };
89fa9d8ea   Dave Jiang   acpi/nfit, libnvd...
168
169
170
171
  enum nvdimm_passphrase_type {
  	NVDIMM_USER,
  	NVDIMM_MASTER,
  };
f29893965   Dave Jiang   acpi/nfit, libnvd...
172
  struct nvdimm_security_ops {
d78c620a2   Dan Williams   libnvdimm/securit...
173
  	unsigned long (*get_flags)(struct nvdimm *nvdimm,
89fa9d8ea   Dave Jiang   acpi/nfit, libnvd...
174
  			enum nvdimm_passphrase_type pass_type);
37833fb79   Dave Jiang   acpi/nfit, libnvd...
175
  	int (*freeze)(struct nvdimm *nvdimm);
4c6926a23   Dave Jiang   acpi/nfit, libnvd...
176
177
  	int (*change_key)(struct nvdimm *nvdimm,
  			const struct nvdimm_key_data *old_data,
89fa9d8ea   Dave Jiang   acpi/nfit, libnvd...
178
179
  			const struct nvdimm_key_data *new_data,
  			enum nvdimm_passphrase_type pass_type);
4c6926a23   Dave Jiang   acpi/nfit, libnvd...
180
181
  	int (*unlock)(struct nvdimm *nvdimm,
  			const struct nvdimm_key_data *key_data);
03b65b22a   Dave Jiang   acpi/nfit, libnvd...
182
183
  	int (*disable)(struct nvdimm *nvdimm,
  			const struct nvdimm_key_data *key_data);
64e77c8c0   Dave Jiang   acpi/nfit, libnvd...
184
  	int (*erase)(struct nvdimm *nvdimm,
89fa9d8ea   Dave Jiang   acpi/nfit, libnvd...
185
186
  			const struct nvdimm_key_data *key_data,
  			enum nvdimm_passphrase_type pass_type);
7d988097c   Dave Jiang   acpi/nfit, libnvd...
187
188
189
  	int (*overwrite)(struct nvdimm *nvdimm,
  			const struct nvdimm_key_data *key_data);
  	int (*query_overwrite)(struct nvdimm *nvdimm);
f29893965   Dave Jiang   acpi/nfit, libnvd...
190
  };
48001ea50   Dan Williams   PM, libnvdimm: Ad...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  enum nvdimm_fwa_state {
  	NVDIMM_FWA_INVALID,
  	NVDIMM_FWA_IDLE,
  	NVDIMM_FWA_ARMED,
  	NVDIMM_FWA_BUSY,
  	NVDIMM_FWA_ARM_OVERFLOW,
  };
  
  enum nvdimm_fwa_trigger {
  	NVDIMM_FWA_ARM,
  	NVDIMM_FWA_DISARM,
  };
  
  enum nvdimm_fwa_capability {
  	NVDIMM_FWA_CAP_INVALID,
  	NVDIMM_FWA_CAP_NONE,
  	NVDIMM_FWA_CAP_QUIESCE,
  	NVDIMM_FWA_CAP_LIVE,
  };
  
  enum nvdimm_fwa_result {
  	NVDIMM_FWA_RESULT_INVALID,
  	NVDIMM_FWA_RESULT_NONE,
  	NVDIMM_FWA_RESULT_SUCCESS,
  	NVDIMM_FWA_RESULT_NOTSTAGED,
  	NVDIMM_FWA_RESULT_NEEDRESET,
  	NVDIMM_FWA_RESULT_FAIL,
  };
  
  struct nvdimm_bus_fw_ops {
  	enum nvdimm_fwa_state (*activate_state)
  		(struct nvdimm_bus_descriptor *nd_desc);
  	enum nvdimm_fwa_capability (*capability)
  		(struct nvdimm_bus_descriptor *nd_desc);
  	int (*activate)(struct nvdimm_bus_descriptor *nd_desc);
  };
  
  struct nvdimm_fw_ops {
  	enum nvdimm_fwa_state (*activate_state)(struct nvdimm *nvdimm);
  	enum nvdimm_fwa_result (*activate_result)(struct nvdimm *nvdimm);
  	int (*arm)(struct nvdimm *nvdimm, enum nvdimm_fwa_trigger arg);
  };
aa9ad44a4   Dave Jiang   libnvdimm: move p...
233
234
235
236
237
238
  void badrange_init(struct badrange *badrange);
  int badrange_add(struct badrange *badrange, u64 addr, u64 length);
  void badrange_forget(struct badrange *badrange, phys_addr_t start,
  		unsigned int len);
  int nvdimm_bus_add_badrange(struct nvdimm_bus *nvdimm_bus, u64 addr,
  		u64 length);
bc9775d86   Dan Williams   libnvdimm: move -...
239
240
  struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
  		struct nvdimm_bus_descriptor *nfit_desc);
b94d5230d   Dan Williams   libnvdimm, nfit: ...
241
  void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus);
45def22c1   Dan Williams   libnvdimm: contro...
242
  struct nvdimm_bus *to_nvdimm_bus(struct device *dev);
f29893965   Dave Jiang   acpi/nfit, libnvd...
243
  struct nvdimm_bus *nvdimm_to_bus(struct nvdimm *nvdimm);
e6dfb2de4   Dan Williams   libnvdimm, nfit: ...
244
  struct nvdimm *to_nvdimm(struct device *dev);
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
245
  struct nd_region *to_nd_region(struct device *dev);
243f29fe4   Dan Williams   libnvdimm: add an...
246
  struct device *nd_region_dev(struct nd_region *nd_region);
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
247
  struct nd_blk_region *to_nd_blk_region(struct device *dev);
45def22c1   Dan Williams   libnvdimm: contro...
248
  struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus);
37b137ff8   Vishal Verma   nfit, libnvdimm: ...
249
  struct device *to_nvdimm_bus_dev(struct nvdimm_bus *nvdimm_bus);
e6dfb2de4   Dan Williams   libnvdimm, nfit: ...
250
  const char *nvdimm_name(struct nvdimm *nvdimm);
ba9c8dd3c   Dan Williams   acpi, nfit: add d...
251
  struct kobject *nvdimm_kobj(struct nvdimm *nvdimm);
e3654eca7   Dan Williams   nfit, libnvdimm: ...
252
  unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm);
e6dfb2de4   Dan Williams   libnvdimm, nfit: ...
253
  void *nvdimm_provider_data(struct nvdimm *nvdimm);
d6548ae4d   Dave Jiang   acpi/nfit, libnvd...
254
255
256
  struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
  		void *provider_data, const struct attribute_group **groups,
  		unsigned long flags, unsigned long cmd_mask, int num_flush,
f29893965   Dave Jiang   acpi/nfit, libnvd...
257
  		struct resource *flush_wpq, const char *dimm_id,
a1facc1ff   Dan Williams   ACPI: NFIT: Add r...
258
259
  		const struct nvdimm_security_ops *sec_ops,
  		const struct nvdimm_fw_ops *fw_ops);
d6548ae4d   Dave Jiang   acpi/nfit, libnvd...
260
261
262
263
264
265
  static inline struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus,
  		void *provider_data, const struct attribute_group **groups,
  		unsigned long flags, unsigned long cmd_mask, int num_flush,
  		struct resource *flush_wpq)
  {
  	return __nvdimm_create(nvdimm_bus, provider_data, groups, flags,
a1facc1ff   Dan Williams   ACPI: NFIT: Add r...
266
  			cmd_mask, num_flush, flush_wpq, NULL, NULL, NULL);
d6548ae4d   Dave Jiang   acpi/nfit, libnvd...
267
  }
62232e45f   Dan Williams   libnvdimm: contro...
268
269
270
271
272
273
  const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd);
  const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd);
  u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
  		const struct nd_cmd_desc *desc, int idx, void *buf);
  u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
  		const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
efda1b5d8   Dan Williams   acpi, nfit, libnv...
274
  		const u32 *out_field, unsigned long remainder);
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
275
  int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count);
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
276
277
278
279
280
281
  struct nd_region *nvdimm_pmem_region_create(struct nvdimm_bus *nvdimm_bus,
  		struct nd_region_desc *ndr_desc);
  struct nd_region *nvdimm_blk_region_create(struct nvdimm_bus *nvdimm_bus,
  		struct nd_region_desc *ndr_desc);
  struct nd_region *nvdimm_volatile_region_create(struct nvdimm_bus *nvdimm_bus,
  		struct nd_region_desc *ndr_desc);
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
282
283
284
285
  void *nd_region_provider_data(struct nd_region *nd_region);
  void *nd_blk_region_provider_data(struct nd_blk_region *ndbr);
  void nd_blk_region_set_provider_data(struct nd_blk_region *ndbr, void *data);
  struct nvdimm *nd_blk_region_to_dimm(struct nd_blk_region *ndbr);
ca6a4657e   Dan Williams   x86, libnvdimm, p...
286
  unsigned long nd_blk_memremap_flags(struct nd_blk_region *ndbr);
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
287
288
  unsigned int nd_region_acquire_lane(struct nd_region *nd_region);
  void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane);
eaf961536   Dan Williams   libnvdimm, nfit: ...
289
  u64 nd_fletcher64(void *addr, size_t len, bool le);
c5d4355d1   Pankaj Gupta   libnvdimm: nd_reg...
290
291
  int nvdimm_flush(struct nd_region *nd_region, struct bio *bio);
  int generic_nvdimm_flush(struct nd_region *nd_region);
f284a4f23   Dan Williams   libnvdimm: introd...
292
  int nvdimm_has_flush(struct nd_region *nd_region);
0b277961f   Dan Williams   libnvdimm, pmem: ...
293
  int nvdimm_has_cache(struct nd_region *nd_region);
7d988097c   Dave Jiang   acpi/nfit, libnvd...
294
  int nvdimm_in_overwrite(struct nvdimm *nvdimm);
fefc1d97f   Pankaj Gupta   libnvdimm: add da...
295
  bool is_nvdimm_sync(struct nd_region *nd_region);
5deb67f77   Robin Murphy   libnvdimm, nd_blk...
296

f29893965   Dave Jiang   acpi/nfit, libnvd...
297
298
299
300
301
302
303
304
  static inline int nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, void *buf,
  		unsigned int buf_len, int *cmd_rc)
  {
  	struct nvdimm_bus *nvdimm_bus = nvdimm_to_bus(nvdimm);
  	struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus);
  
  	return nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len, cmd_rc);
  }
5deb67f77   Robin Murphy   libnvdimm, nd_blk...
305
306
307
308
309
310
311
312
313
314
315
316
317
  #ifdef CONFIG_ARCH_HAS_PMEM_API
  #define ARCH_MEMREMAP_PMEM MEMREMAP_WB
  void arch_wb_cache_pmem(void *addr, size_t size);
  void arch_invalidate_pmem(void *addr, size_t size);
  #else
  #define ARCH_MEMREMAP_PMEM MEMREMAP_WT
  static inline void arch_wb_cache_pmem(void *addr, size_t size)
  {
  }
  static inline void arch_invalidate_pmem(void *addr, size_t size)
  {
  }
  #endif
b94d5230d   Dan Williams   libnvdimm, nfit: ...
318
  #endif /* __LIBNVDIMM_H__ */