xref: /openbmc/linux/drivers/nvdimm/nd.h (revision d1c6e08e7503649e4a4f3f9e700e2c05300b6379)
15b497af4SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
24d88a97aSDan Williams /*
34d88a97aSDan Williams  * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
44d88a97aSDan Williams  */
54d88a97aSDan Williams #ifndef __ND_H__
64d88a97aSDan Williams #define __ND_H__
71f7df6f8SDan Williams #include <linux/libnvdimm.h>
8200c79daSDan Williams #include <linux/badblocks.h>
9f0dc089cSDan Williams #include <linux/blkdev.h>
104d88a97aSDan Williams #include <linux/device.h>
114d88a97aSDan Williams #include <linux/mutex.h>
124d88a97aSDan Williams #include <linux/ndctl.h>
13bf9bccc1SDan Williams #include <linux/types.h>
1471999466SDan Williams #include <linux/nd.h>
154a826c83SDan Williams #include "label.h"
164d88a97aSDan Williams 
178c2f7e86SDan Williams enum {
185212e11fSVishal Verma 	/*
195212e11fSVishal Verma 	 * Limits the maximum number of block apertures a dimm can
205212e11fSVishal Verma 	 * support and is an input to the geometry/on-disk-format of a
215212e11fSVishal Verma 	 * BTT instance
225212e11fSVishal Verma 	 */
235212e11fSVishal Verma 	ND_MAX_LANES = 256,
24fcae6957SVishal Verma 	INT_LBASIZE_ALIGNMENT = 64,
253ae3d67bSVishal Verma 	NVDIMM_IO_ATOMIC = 1,
268c2f7e86SDan Williams };
278c2f7e86SDan Williams 
284d88a97aSDan Williams struct nvdimm_drvdata {
294d88a97aSDan Williams 	struct device *dev;
3002881768SDan Williams 	int nslabel_size;
314d88a97aSDan Williams 	struct nd_cmd_get_config_size nsarea;
324d88a97aSDan Williams 	void *data;
334a826c83SDan Williams 	int ns_current, ns_next;
344a826c83SDan Williams 	struct resource dpa;
35bf9bccc1SDan Williams 	struct kref kref;
364d88a97aSDan Williams };
374d88a97aSDan Williams 
38b4366a82SDan Williams static inline const u8 *nsl_ref_name(struct nvdimm_drvdata *ndd,
39b4366a82SDan Williams 				     struct nd_namespace_label *nd_label)
40b4366a82SDan Williams {
41b4366a82SDan Williams 	return nd_label->name;
42b4366a82SDan Williams }
43b4366a82SDan Williams 
44b4366a82SDan Williams static inline u8 *nsl_get_name(struct nvdimm_drvdata *ndd,
45b4366a82SDan Williams 			       struct nd_namespace_label *nd_label, u8 *name)
46b4366a82SDan Williams {
47b4366a82SDan Williams 	return memcpy(name, nd_label->name, NSLABEL_NAME_LEN);
48b4366a82SDan Williams }
49b4366a82SDan Williams 
508176f147SDan Williams static inline u8 *nsl_set_name(struct nvdimm_drvdata *ndd,
518176f147SDan Williams 			       struct nd_namespace_label *nd_label, u8 *name)
528176f147SDan Williams {
538176f147SDan Williams 	if (!name)
548176f147SDan Williams 		return NULL;
558176f147SDan Williams 	return memcpy(nd_label->name, name, NSLABEL_NAME_LEN);
568176f147SDan Williams }
578176f147SDan Williams 
58b4366a82SDan Williams static inline u32 nsl_get_slot(struct nvdimm_drvdata *ndd,
59b4366a82SDan Williams 			       struct nd_namespace_label *nd_label)
60b4366a82SDan Williams {
61b4366a82SDan Williams 	return __le32_to_cpu(nd_label->slot);
62b4366a82SDan Williams }
63b4366a82SDan Williams 
648176f147SDan Williams static inline void nsl_set_slot(struct nvdimm_drvdata *ndd,
658176f147SDan Williams 				struct nd_namespace_label *nd_label, u32 slot)
668176f147SDan Williams {
678176f147SDan Williams 	nd_label->slot = __cpu_to_le32(slot);
688176f147SDan Williams }
698176f147SDan Williams 
70b4366a82SDan Williams static inline u64 nsl_get_checksum(struct nvdimm_drvdata *ndd,
71b4366a82SDan Williams 				   struct nd_namespace_label *nd_label)
72b4366a82SDan Williams {
73b4366a82SDan Williams 	return __le64_to_cpu(nd_label->checksum);
74b4366a82SDan Williams }
75b4366a82SDan Williams 
768176f147SDan Williams static inline void nsl_set_checksum(struct nvdimm_drvdata *ndd,
778176f147SDan Williams 				    struct nd_namespace_label *nd_label,
788176f147SDan Williams 				    u64 checksum)
798176f147SDan Williams {
808176f147SDan Williams 	nd_label->checksum = __cpu_to_le64(checksum);
818176f147SDan Williams }
828176f147SDan Williams 
83b4366a82SDan Williams static inline u32 nsl_get_flags(struct nvdimm_drvdata *ndd,
84b4366a82SDan Williams 				struct nd_namespace_label *nd_label)
85b4366a82SDan Williams {
86b4366a82SDan Williams 	return __le32_to_cpu(nd_label->flags);
87b4366a82SDan Williams }
88b4366a82SDan Williams 
898176f147SDan Williams static inline void nsl_set_flags(struct nvdimm_drvdata *ndd,
908176f147SDan Williams 				 struct nd_namespace_label *nd_label, u32 flags)
918176f147SDan Williams {
928176f147SDan Williams 	nd_label->flags = __cpu_to_le32(flags);
938176f147SDan Williams }
948176f147SDan Williams 
95b4366a82SDan Williams static inline u64 nsl_get_dpa(struct nvdimm_drvdata *ndd,
96b4366a82SDan Williams 			      struct nd_namespace_label *nd_label)
97b4366a82SDan Williams {
98b4366a82SDan Williams 	return __le64_to_cpu(nd_label->dpa);
99b4366a82SDan Williams }
100b4366a82SDan Williams 
1018176f147SDan Williams static inline void nsl_set_dpa(struct nvdimm_drvdata *ndd,
1028176f147SDan Williams 			       struct nd_namespace_label *nd_label, u64 dpa)
1038176f147SDan Williams {
1048176f147SDan Williams 	nd_label->dpa = __cpu_to_le64(dpa);
1058176f147SDan Williams }
1068176f147SDan Williams 
107b4366a82SDan Williams static inline u64 nsl_get_rawsize(struct nvdimm_drvdata *ndd,
108b4366a82SDan Williams 				  struct nd_namespace_label *nd_label)
109b4366a82SDan Williams {
110b4366a82SDan Williams 	return __le64_to_cpu(nd_label->rawsize);
111b4366a82SDan Williams }
112b4366a82SDan Williams 
1138176f147SDan Williams static inline void nsl_set_rawsize(struct nvdimm_drvdata *ndd,
1148176f147SDan Williams 				   struct nd_namespace_label *nd_label,
1158176f147SDan Williams 				   u64 rawsize)
1168176f147SDan Williams {
1178176f147SDan Williams 	nd_label->rawsize = __cpu_to_le64(rawsize);
1188176f147SDan Williams }
1198176f147SDan Williams 
120b4366a82SDan Williams static inline u64 nsl_get_isetcookie(struct nvdimm_drvdata *ndd,
121b4366a82SDan Williams 				     struct nd_namespace_label *nd_label)
122b4366a82SDan Williams {
123b4366a82SDan Williams 	return __le64_to_cpu(nd_label->isetcookie);
124b4366a82SDan Williams }
125b4366a82SDan Williams 
1268176f147SDan Williams static inline void nsl_set_isetcookie(struct nvdimm_drvdata *ndd,
1278176f147SDan Williams 				      struct nd_namespace_label *nd_label,
1288176f147SDan Williams 				      u64 isetcookie)
1298176f147SDan Williams {
1308176f147SDan Williams 	nd_label->isetcookie = __cpu_to_le64(isetcookie);
1318176f147SDan Williams }
1328176f147SDan Williams 
1339761b02dSDan Williams static inline bool nsl_validate_isetcookie(struct nvdimm_drvdata *ndd,
1349761b02dSDan Williams 					   struct nd_namespace_label *nd_label,
1359761b02dSDan Williams 					   u64 cookie)
1369761b02dSDan Williams {
1379761b02dSDan Williams 	return cookie == __le64_to_cpu(nd_label->isetcookie);
1389761b02dSDan Williams }
1399761b02dSDan Williams 
140b4366a82SDan Williams static inline u16 nsl_get_position(struct nvdimm_drvdata *ndd,
141b4366a82SDan Williams 				   struct nd_namespace_label *nd_label)
142b4366a82SDan Williams {
143b4366a82SDan Williams 	return __le16_to_cpu(nd_label->position);
144b4366a82SDan Williams }
145b4366a82SDan Williams 
1468176f147SDan Williams static inline void nsl_set_position(struct nvdimm_drvdata *ndd,
1478176f147SDan Williams 				    struct nd_namespace_label *nd_label,
1488176f147SDan Williams 				    u16 position)
1498176f147SDan Williams {
1508176f147SDan Williams 	nd_label->position = __cpu_to_le16(position);
1518176f147SDan Williams }
1528176f147SDan Williams 
1538176f147SDan Williams 
154b4366a82SDan Williams static inline u16 nsl_get_nlabel(struct nvdimm_drvdata *ndd,
155b4366a82SDan Williams 				 struct nd_namespace_label *nd_label)
156b4366a82SDan Williams {
157b4366a82SDan Williams 	return __le16_to_cpu(nd_label->nlabel);
158b4366a82SDan Williams }
159b4366a82SDan Williams 
1608176f147SDan Williams static inline void nsl_set_nlabel(struct nvdimm_drvdata *ndd,
1618176f147SDan Williams 				  struct nd_namespace_label *nd_label,
1628176f147SDan Williams 				  u16 nlabel)
1638176f147SDan Williams {
1648176f147SDan Williams 	nd_label->nlabel = __cpu_to_le16(nlabel);
1658176f147SDan Williams }
1668176f147SDan Williams 
167b4366a82SDan Williams static inline u64 nsl_get_lbasize(struct nvdimm_drvdata *ndd,
168b4366a82SDan Williams 				  struct nd_namespace_label *nd_label)
169b4366a82SDan Williams {
170b4366a82SDan Williams 	return __le64_to_cpu(nd_label->lbasize);
171b4366a82SDan Williams }
172b4366a82SDan Williams 
1738176f147SDan Williams static inline void nsl_set_lbasize(struct nvdimm_drvdata *ndd,
1748176f147SDan Williams 				   struct nd_namespace_label *nd_label,
1758176f147SDan Williams 				   u64 lbasize)
1768176f147SDan Williams {
1778176f147SDan Williams 	nd_label->lbasize = __cpu_to_le64(lbasize);
1788176f147SDan Williams }
1798176f147SDan Williams 
180*d1c6e08eSDan Williams static inline const uuid_t *nsl_get_uuid(struct nvdimm_drvdata *ndd,
181*d1c6e08eSDan Williams 					 struct nd_namespace_label *nd_label,
182*d1c6e08eSDan Williams 					 uuid_t *uuid)
183*d1c6e08eSDan Williams {
184*d1c6e08eSDan Williams 	import_uuid(uuid, nd_label->uuid);
185*d1c6e08eSDan Williams 	return uuid;
186*d1c6e08eSDan Williams }
187*d1c6e08eSDan Williams 
188*d1c6e08eSDan Williams static inline const uuid_t *nsl_set_uuid(struct nvdimm_drvdata *ndd,
189*d1c6e08eSDan Williams 					 struct nd_namespace_label *nd_label,
190*d1c6e08eSDan Williams 					 const uuid_t *uuid)
191*d1c6e08eSDan Williams {
192*d1c6e08eSDan Williams 	export_uuid(nd_label->uuid, uuid);
193*d1c6e08eSDan Williams 	return uuid;
194*d1c6e08eSDan Williams }
195*d1c6e08eSDan Williams 
196*d1c6e08eSDan Williams static inline bool nsl_uuid_equal(struct nvdimm_drvdata *ndd,
197*d1c6e08eSDan Williams 				  struct nd_namespace_label *nd_label,
198*d1c6e08eSDan Williams 				  const uuid_t *uuid)
199*d1c6e08eSDan Williams {
200*d1c6e08eSDan Williams 	uuid_t tmp;
201*d1c6e08eSDan Williams 
202*d1c6e08eSDan Williams 	import_uuid(&tmp, nd_label->uuid);
203*d1c6e08eSDan Williams 	return uuid_equal(&tmp, uuid);
204*d1c6e08eSDan Williams }
205*d1c6e08eSDan Williams 
206*d1c6e08eSDan Williams static inline const u8 *nsl_uuid_raw(struct nvdimm_drvdata *ndd,
207*d1c6e08eSDan Williams 				     struct nd_namespace_label *nd_label)
208*d1c6e08eSDan Williams {
209*d1c6e08eSDan Williams 	return nd_label->uuid;
210*d1c6e08eSDan Williams }
211*d1c6e08eSDan Williams 
212f56541a7SDan Williams bool nsl_validate_blk_isetcookie(struct nvdimm_drvdata *ndd,
213f56541a7SDan Williams 				 struct nd_namespace_label *nd_label,
214f56541a7SDan Williams 				 u64 isetcookie);
2158b03aa0eSDan Williams bool nsl_validate_type_guid(struct nvdimm_drvdata *ndd,
2168b03aa0eSDan Williams 			    struct nd_namespace_label *nd_label, guid_t *guid);
217a6e6d722SDan Williams enum nvdimm_claim_class nsl_get_claim_class(struct nvdimm_drvdata *ndd,
218a6e6d722SDan Williams 					    struct nd_namespace_label *nd_label);
219f56541a7SDan Williams 
220e5ae3b25SDan Williams struct nd_region_data {
221e5ae3b25SDan Williams 	int ns_count;
222e5ae3b25SDan Williams 	int ns_active;
223595c7307SDan Williams 	unsigned int hints_shift;
2249106137cSGustavo A. R. Silva 	void __iomem *flush_wpq[];
2253d88002eSDan Williams };
2263d88002eSDan Williams 
227595c7307SDan Williams static inline void __iomem *ndrd_get_flush_wpq(struct nd_region_data *ndrd,
228595c7307SDan Williams 		int dimm, int hint)
229595c7307SDan Williams {
230595c7307SDan Williams 	unsigned int num = 1 << ndrd->hints_shift;
231595c7307SDan Williams 	unsigned int mask = num - 1;
232595c7307SDan Williams 
233595c7307SDan Williams 	return ndrd->flush_wpq[dimm * num + (hint & mask)];
234595c7307SDan Williams }
235595c7307SDan Williams 
236595c7307SDan Williams static inline void ndrd_set_flush_wpq(struct nd_region_data *ndrd, int dimm,
237595c7307SDan Williams 		int hint, void __iomem *flush)
238595c7307SDan Williams {
239595c7307SDan Williams 	unsigned int num = 1 << ndrd->hints_shift;
240595c7307SDan Williams 	unsigned int mask = num - 1;
241595c7307SDan Williams 
242595c7307SDan Williams 	ndrd->flush_wpq[dimm * num + (hint & mask)] = flush;
243595c7307SDan Williams }
244595c7307SDan Williams 
2454a826c83SDan Williams static inline struct nd_namespace_index *to_namespace_index(
2464a826c83SDan Williams 		struct nvdimm_drvdata *ndd, int i)
2474a826c83SDan Williams {
2484a826c83SDan Williams 	if (i < 0)
2494a826c83SDan Williams 		return NULL;
2504a826c83SDan Williams 
2514a826c83SDan Williams 	return ndd->data + sizeof_namespace_index(ndd) * i;
2524a826c83SDan Williams }
2534a826c83SDan Williams 
2544a826c83SDan Williams static inline struct nd_namespace_index *to_current_namespace_index(
2554a826c83SDan Williams 		struct nvdimm_drvdata *ndd)
2564a826c83SDan Williams {
2574a826c83SDan Williams 	return to_namespace_index(ndd, ndd->ns_current);
2584a826c83SDan Williams }
2594a826c83SDan Williams 
2604a826c83SDan Williams static inline struct nd_namespace_index *to_next_namespace_index(
2614a826c83SDan Williams 		struct nvdimm_drvdata *ndd)
2624a826c83SDan Williams {
2634a826c83SDan Williams 	return to_namespace_index(ndd, ndd->ns_next);
2644a826c83SDan Williams }
2654a826c83SDan Williams 
266564e871aSDan Williams unsigned sizeof_namespace_label(struct nvdimm_drvdata *ndd);
267564e871aSDan Williams 
268564e871aSDan Williams #define namespace_label_has(ndd, field) \
269564e871aSDan Williams 	(offsetof(struct nd_namespace_label, field) \
270564e871aSDan Williams 		< sizeof_namespace_label(ndd))
271564e871aSDan Williams 
2724a826c83SDan Williams #define nd_dbg_dpa(r, d, res, fmt, arg...) \
2734a826c83SDan Williams 	dev_dbg((r) ? &(r)->dev : (d)->dev, "%s: %.13s: %#llx @ %#llx " fmt, \
2744a826c83SDan Williams 		(r) ? dev_name((d)->dev) : "", res ? res->name : "null", \
2754a826c83SDan Williams 		(unsigned long long) (res ? resource_size(res) : 0), \
2764a826c83SDan Williams 		(unsigned long long) (res ? res->start : 0), ##arg)
2774a826c83SDan Williams 
278bf9bccc1SDan Williams #define for_each_dpa_resource(ndd, res) \
279bf9bccc1SDan Williams 	for (res = (ndd)->dpa.child; res; res = res->sibling)
280bf9bccc1SDan Williams 
2814a826c83SDan Williams #define for_each_dpa_resource_safe(ndd, res, next) \
2824a826c83SDan Williams 	for (res = (ndd)->dpa.child, next = res ? res->sibling : NULL; \
2834a826c83SDan Williams 			res; res = next, next = next ? next->sibling : NULL)
2844a826c83SDan Williams 
2855212e11fSVishal Verma struct nd_percpu_lane {
2865212e11fSVishal Verma 	int count;
2875212e11fSVishal Verma 	spinlock_t lock;
2885212e11fSVishal Verma };
2895212e11fSVishal Verma 
290c4703ce1SDan Williams enum nd_label_flags {
291c4703ce1SDan Williams 	ND_LABEL_REAP,
292c4703ce1SDan Williams };
293ae8219f1SDan Williams struct nd_label_ent {
294ae8219f1SDan Williams 	struct list_head list;
295c4703ce1SDan Williams 	unsigned long flags;
296ae8219f1SDan Williams 	struct nd_namespace_label *label;
297ae8219f1SDan Williams };
298ae8219f1SDan Williams 
299ae8219f1SDan Williams enum nd_mapping_lock_class {
300ae8219f1SDan Williams 	ND_MAPPING_CLASS0,
301ae8219f1SDan Williams 	ND_MAPPING_UUID_SCAN,
302ae8219f1SDan Williams };
303ae8219f1SDan Williams 
30444c462ebSDan Williams struct nd_mapping {
30544c462ebSDan Williams 	struct nvdimm *nvdimm;
30644c462ebSDan Williams 	u64 start;
30744c462ebSDan Williams 	u64 size;
308401c0a19SDan Williams 	int position;
309ae8219f1SDan Williams 	struct list_head labels;
310ae8219f1SDan Williams 	struct mutex lock;
31144c462ebSDan Williams 	/*
31244c462ebSDan Williams 	 * @ndd is for private use at region enable / disable time for
31344c462ebSDan Williams 	 * get_ndd() + put_ndd(), all other nd_mapping to ndd
31444c462ebSDan Williams 	 * conversions use to_ndd() which respects enabled state of the
31544c462ebSDan Williams 	 * nvdimm.
31644c462ebSDan Williams 	 */
31744c462ebSDan Williams 	struct nvdimm_drvdata *ndd;
31844c462ebSDan Williams };
31944c462ebSDan Williams 
3201f7df6f8SDan Williams struct nd_region {
3211f7df6f8SDan Williams 	struct device dev;
3221b40e09aSDan Williams 	struct ida ns_ida;
3238c2f7e86SDan Williams 	struct ida btt_ida;
324e1455744SDan Williams 	struct ida pfn_ida;
325cd03412aSDan Williams 	struct ida dax_ida;
326004f1afbSDan Williams 	unsigned long flags;
327bf9bccc1SDan Williams 	struct device *ns_seed;
3288c2f7e86SDan Williams 	struct device *btt_seed;
329e1455744SDan Williams 	struct device *pfn_seed;
330cd03412aSDan Williams 	struct device *dax_seed;
3312522afb8SDan Williams 	unsigned long align;
3321f7df6f8SDan Williams 	u16 ndr_mappings;
3331f7df6f8SDan Williams 	u64 ndr_size;
3341f7df6f8SDan Williams 	u64 ndr_start;
3358fc5c735SDan Williams 	int id, num_lanes, ro, numa_node, target_node;
3361f7df6f8SDan Williams 	void *provider_data;
337975750a9SToshi Kani 	struct kernfs_node *bb_state;
3386a6bef90SDave Jiang 	struct badblocks bb;
339eaf96153SDan Williams 	struct nd_interleave_set *nd_set;
3405212e11fSVishal Verma 	struct nd_percpu_lane __percpu *lane;
341c5d4355dSPankaj Gupta 	int (*flush)(struct nd_region *nd_region, struct bio *bio);
3429106137cSGustavo A. R. Silva 	struct nd_mapping mapping[];
3431f7df6f8SDan Williams };
3441f7df6f8SDan Williams 
345047fc8a1SRoss Zwisler struct nd_blk_region {
346047fc8a1SRoss Zwisler 	int (*enable)(struct nvdimm_bus *nvdimm_bus, struct device *dev);
347047fc8a1SRoss Zwisler 	int (*do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
348047fc8a1SRoss Zwisler 			void *iobuf, u64 len, int rw);
349047fc8a1SRoss Zwisler 	void *blk_provider_data;
350047fc8a1SRoss Zwisler 	struct nd_region nd_region;
351047fc8a1SRoss Zwisler };
352047fc8a1SRoss Zwisler 
3534a826c83SDan Williams /*
3544a826c83SDan Williams  * Lookup next in the repeating sequence of 01, 10, and 11.
3554a826c83SDan Williams  */
3564a826c83SDan Williams static inline unsigned nd_inc_seq(unsigned seq)
3574a826c83SDan Williams {
3584a826c83SDan Williams 	static const unsigned next[] = { 0, 2, 3, 1 };
3594a826c83SDan Williams 
3604a826c83SDan Williams 	return next[seq & 3];
3614a826c83SDan Williams }
362f524bf27SDan Williams 
3635212e11fSVishal Verma struct btt;
3648c2f7e86SDan Williams struct nd_btt {
3658c2f7e86SDan Williams 	struct device dev;
3668c2f7e86SDan Williams 	struct nd_namespace_common *ndns;
3675212e11fSVishal Verma 	struct btt *btt;
3688c2f7e86SDan Williams 	unsigned long lbasize;
369abe8b4e3SVishal Verma 	u64 size;
370*d1c6e08eSDan Williams 	uuid_t *uuid;
3718c2f7e86SDan Williams 	int id;
37214e49454SVishal Verma 	int initial_offset;
37314e49454SVishal Verma 	u16 version_major;
37414e49454SVishal Verma 	u16 version_minor;
3758c2f7e86SDan Williams };
3768c2f7e86SDan Williams 
377e1455744SDan Williams enum nd_pfn_mode {
378e1455744SDan Williams 	PFN_MODE_NONE,
379e1455744SDan Williams 	PFN_MODE_RAM,
380e1455744SDan Williams 	PFN_MODE_PMEM,
381e1455744SDan Williams };
382e1455744SDan Williams 
383e1455744SDan Williams struct nd_pfn {
384e1455744SDan Williams 	int id;
385*d1c6e08eSDan Williams 	uuid_t *uuid;
386e1455744SDan Williams 	struct device dev;
387315c5625SDan Williams 	unsigned long align;
388e1455744SDan Williams 	unsigned long npfns;
389e1455744SDan Williams 	enum nd_pfn_mode mode;
390e1455744SDan Williams 	struct nd_pfn_sb *pfn_sb;
391e1455744SDan Williams 	struct nd_namespace_common *ndns;
392e1455744SDan Williams };
393e1455744SDan Williams 
394cd03412aSDan Williams struct nd_dax {
395cd03412aSDan Williams 	struct nd_pfn nd_pfn;
396cd03412aSDan Williams };
397cd03412aSDan Williams 
3988f4b01fcSAneesh Kumar K.V static inline u32 nd_info_block_reserve(void)
3998f4b01fcSAneesh Kumar K.V {
4008f4b01fcSAneesh Kumar K.V 	return ALIGN(SZ_8K, PAGE_SIZE);
4018f4b01fcSAneesh Kumar K.V }
4028f4b01fcSAneesh Kumar K.V 
4034d88a97aSDan Williams enum nd_async_mode {
4044d88a97aSDan Williams 	ND_SYNC,
4054d88a97aSDan Williams 	ND_ASYNC,
4064d88a97aSDan Williams };
4074d88a97aSDan Williams 
40841cd8b70SVishal Verma int nd_integrity_init(struct gendisk *disk, unsigned long meta_size);
409bf9bccc1SDan Williams void wait_nvdimm_bus_probe_idle(struct device *dev);
4104d88a97aSDan Williams void nd_device_register(struct device *dev);
4114d88a97aSDan Williams void nd_device_unregister(struct device *dev, enum nd_async_mode mode);
41271999466SDan Williams void nd_device_notify(struct device *dev, enum nvdimm_event event);
413*d1c6e08eSDan Williams int nd_uuid_store(struct device *dev, uuid_t **uuid_out, const char *buf,
414bf9bccc1SDan Williams 		size_t len);
415b2c48f9fSDan Williams ssize_t nd_size_select_show(unsigned long current_size,
4161b40e09aSDan Williams 		const unsigned long *supported, char *buf);
417b2c48f9fSDan Williams ssize_t nd_size_select_store(struct device *dev, const char *buf,
418b2c48f9fSDan Williams 		unsigned long *current_size, const unsigned long *supported);
4194d88a97aSDan Williams int __init nvdimm_init(void);
4203d88002eSDan Williams int __init nd_region_init(void);
421b3fde74eSDan Williams int __init nd_label_init(void);
4224d88a97aSDan Williams void nvdimm_exit(void);
4233d88002eSDan Williams void nd_region_exit(void);
424bf9bccc1SDan Williams struct nvdimm;
425adbb6829SDan Williams extern const struct attribute_group nd_device_attribute_group;
426e2f6a0e3SDan Williams extern const struct attribute_group nd_numa_attribute_group;
427e755799aSDan Williams extern const struct attribute_group *nvdimm_bus_attribute_groups[];
428bf9bccc1SDan Williams struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping);
429aee65987SToshi Kani int nvdimm_check_config_data(struct device *dev);
4304d88a97aSDan Williams int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd);
4314d88a97aSDan Williams int nvdimm_init_config_data(struct nvdimm_drvdata *ndd);
4322d657d17SAlexander Duyck int nvdimm_get_config_data(struct nvdimm_drvdata *ndd, void *buf,
4332d657d17SAlexander Duyck 			   size_t offset, size_t len);
434f524bf27SDan Williams int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
435f524bf27SDan Williams 		void *buf, size_t len);
43659e64739SDan Williams long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
43759e64739SDan Williams 		unsigned int len);
438a0e37452SDan Williams void nvdimm_set_labeling(struct device *dev);
4398f078b38SDan Williams void nvdimm_set_locked(struct device *dev);
440d34cb808SDan Williams void nvdimm_clear_locked(struct device *dev);
4411cd73865SDan Williams int nvdimm_security_setup_events(struct device *dev);
4424c6926a2SDave Jiang #if IS_ENABLED(CONFIG_NVDIMM_KEYS)
4434c6926a2SDave Jiang int nvdimm_security_unlock(struct device *dev);
4444c6926a2SDave Jiang #else
4454c6926a2SDave Jiang static inline int nvdimm_security_unlock(struct device *dev)
4464c6926a2SDave Jiang {
4474c6926a2SDave Jiang 	return 0;
4484c6926a2SDave Jiang }
4494c6926a2SDave Jiang #endif
4508c2f7e86SDan Williams struct nd_btt *to_nd_btt(struct device *dev);
451e1455744SDan Williams 
452e1455744SDan Williams struct nd_gen_sb {
453e1455744SDan Williams 	char reserved[SZ_4K - 8];
454e1455744SDan Williams 	__le64 checksum;
455e1455744SDan Williams };
456e1455744SDan Williams 
457e1455744SDan Williams u64 nd_sb_checksum(struct nd_gen_sb *sb);
4588c2f7e86SDan Williams #if IS_ENABLED(CONFIG_BTT)
459200c79daSDan Williams int nd_btt_probe(struct device *dev, struct nd_namespace_common *ndns);
4608c2f7e86SDan Williams bool is_nd_btt(struct device *dev);
4618c2f7e86SDan Williams struct device *nd_btt_create(struct nd_region *nd_region);
4628c2f7e86SDan Williams #else
463e32bc729SDan Williams static inline int nd_btt_probe(struct device *dev,
464200c79daSDan Williams 		struct nd_namespace_common *ndns)
4658c2f7e86SDan Williams {
4668c2f7e86SDan Williams 	return -ENODEV;
4678c2f7e86SDan Williams }
4688c2f7e86SDan Williams 
4698c2f7e86SDan Williams static inline bool is_nd_btt(struct device *dev)
4708c2f7e86SDan Williams {
4718c2f7e86SDan Williams 	return false;
4728c2f7e86SDan Williams }
4738c2f7e86SDan Williams 
4748c2f7e86SDan Williams static inline struct device *nd_btt_create(struct nd_region *nd_region)
4758c2f7e86SDan Williams {
4768c2f7e86SDan Williams 	return NULL;
4778c2f7e86SDan Williams }
4788c2f7e86SDan Williams #endif
479e1455744SDan Williams 
480e1455744SDan Williams struct nd_pfn *to_nd_pfn(struct device *dev);
481e1455744SDan Williams #if IS_ENABLED(CONFIG_NVDIMM_PFN)
4820dd69643SOliver O'Halloran 
483f5376699SAneesh Kumar K.V #define MAX_NVDIMM_ALIGN	4
4840dd69643SOliver O'Halloran 
485200c79daSDan Williams int nd_pfn_probe(struct device *dev, struct nd_namespace_common *ndns);
486e1455744SDan Williams bool is_nd_pfn(struct device *dev);
487e1455744SDan Williams struct device *nd_pfn_create(struct nd_region *nd_region);
488cd03412aSDan Williams struct device *nd_pfn_devinit(struct nd_pfn *nd_pfn,
489cd03412aSDan Williams 		struct nd_namespace_common *ndns);
490c5ed9268SDan Williams int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig);
49178c81cc8SDan Williams extern const struct attribute_group *nd_pfn_attribute_groups[];
492e1455744SDan Williams #else
493200c79daSDan Williams static inline int nd_pfn_probe(struct device *dev,
494200c79daSDan Williams 		struct nd_namespace_common *ndns)
495e1455744SDan Williams {
496e1455744SDan Williams 	return -ENODEV;
497e1455744SDan Williams }
498e1455744SDan Williams 
499e1455744SDan Williams static inline bool is_nd_pfn(struct device *dev)
500e1455744SDan Williams {
501e1455744SDan Williams 	return false;
502e1455744SDan Williams }
503e1455744SDan Williams 
504e1455744SDan Williams static inline struct device *nd_pfn_create(struct nd_region *nd_region)
505e1455744SDan Williams {
506e1455744SDan Williams 	return NULL;
507e1455744SDan Williams }
50832ab0a3fSDan Williams 
509c5ed9268SDan Williams static inline int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig)
51032ab0a3fSDan Williams {
51132ab0a3fSDan Williams 	return -ENODEV;
51232ab0a3fSDan Williams }
513e1455744SDan Williams #endif
514e1455744SDan Williams 
515cd03412aSDan Williams struct nd_dax *to_nd_dax(struct device *dev);
516cd03412aSDan Williams #if IS_ENABLED(CONFIG_NVDIMM_DAX)
517c5ed9268SDan Williams int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns);
518cd03412aSDan Williams bool is_nd_dax(struct device *dev);
519cd03412aSDan Williams struct device *nd_dax_create(struct nd_region *nd_region);
520cd03412aSDan Williams #else
521c5ed9268SDan Williams static inline int nd_dax_probe(struct device *dev,
522c5ed9268SDan Williams 		struct nd_namespace_common *ndns)
523c5ed9268SDan Williams {
524c5ed9268SDan Williams 	return -ENODEV;
525c5ed9268SDan Williams }
526c5ed9268SDan Williams 
527cd03412aSDan Williams static inline bool is_nd_dax(struct device *dev)
528cd03412aSDan Williams {
529cd03412aSDan Williams 	return false;
530cd03412aSDan Williams }
531cd03412aSDan Williams 
532cd03412aSDan Williams static inline struct device *nd_dax_create(struct nd_region *nd_region)
533cd03412aSDan Williams {
534cd03412aSDan Williams 	return NULL;
535cd03412aSDan Williams }
536cd03412aSDan Williams #endif
537cd03412aSDan Williams 
5383d88002eSDan Williams int nd_region_to_nstype(struct nd_region *nd_region);
5393d88002eSDan Williams int nd_region_register_namespaces(struct nd_region *nd_region, int *err);
540c12c48ceSDan Williams u64 nd_region_interleave_set_cookie(struct nd_region *nd_region,
541c12c48ceSDan Williams 		struct nd_namespace_index *nsindex);
54286ef58a4SDan Williams u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region);
5433d88002eSDan Williams void nvdimm_bus_lock(struct device *dev);
5443d88002eSDan Williams void nvdimm_bus_unlock(struct device *dev);
5453d88002eSDan Williams bool is_nvdimm_bus_locked(struct device *dev);
54632f61d67SChristoph Hellwig void nvdimm_check_and_set_ro(struct gendisk *disk);
547bf9bccc1SDan Williams void nvdimm_drvdata_release(struct kref *kref);
548bf9bccc1SDan Williams void put_ndd(struct nvdimm_drvdata *ndd);
5494a826c83SDan Williams int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd);
5504a826c83SDan Williams void nvdimm_free_dpa(struct nvdimm_drvdata *ndd, struct resource *res);
5514a826c83SDan Williams struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd,
5524a826c83SDan Williams 		struct nd_label_id *label_id, resource_size_t start,
5534a826c83SDan Williams 		resource_size_t n);
5548c2f7e86SDan Williams resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns);
55508e6b3c6SDan Williams bool nvdimm_namespace_locked(struct nd_namespace_common *ndns);
5568c2f7e86SDan Williams struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev);
5575212e11fSVishal Verma int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns);
558298f2bc5SDan Williams int nvdimm_namespace_detach_btt(struct nd_btt *nd_btt);
5595212e11fSVishal Verma const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,
5605212e11fSVishal Verma 		char *name);
561f979b13cSDan Williams unsigned int pmem_sector_size(struct nd_namespace_common *ndns);
562a4574f63SDan Williams struct range;
563a3901802SDan Williams void nvdimm_badblocks_populate(struct nd_region *nd_region,
564a4574f63SDan Williams 		struct badblocks *bb, const struct range *range);
5658f4b01fcSAneesh Kumar K.V int devm_namespace_enable(struct device *dev, struct nd_namespace_common *ndns,
5668f4b01fcSAneesh Kumar K.V 		resource_size_t size);
5678f4b01fcSAneesh Kumar K.V void devm_namespace_disable(struct device *dev,
5688f4b01fcSAneesh Kumar K.V 		struct nd_namespace_common *ndns);
569200c79daSDan Williams #if IS_ENABLED(CONFIG_ND_CLAIM)
570e96f0bf2SAneesh Kumar K.V /* max struct page size independent of kernel config */
571e96f0bf2SAneesh Kumar K.V #define MAX_STRUCT_PAGE_SIZE 64
572e8d51348SChristoph Hellwig int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);
573200c79daSDan Williams #else
574e8d51348SChristoph Hellwig static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
575e8d51348SChristoph Hellwig 				   struct dev_pagemap *pgmap)
576ac515c08SDan Williams {
577e8d51348SChristoph Hellwig 	return -ENXIO;
578ac515c08SDan Williams }
579200c79daSDan Williams #endif
580047fc8a1SRoss Zwisler int nd_blk_region_init(struct nd_region *nd_region);
581e5ae3b25SDan Williams int nd_region_activate(struct nd_region *nd_region);
582200c79daSDan Williams static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
583200c79daSDan Williams 		unsigned int len)
584200c79daSDan Williams {
585200c79daSDan Williams 	if (bb->count) {
586200c79daSDan Williams 		sector_t first_bad;
587200c79daSDan Williams 		int num_bad;
588200c79daSDan Williams 
589200c79daSDan Williams 		return !!badblocks_check(bb, sector, len / 512, &first_bad,
590200c79daSDan Williams 				&num_bad);
591200c79daSDan Williams 	}
592200c79daSDan Williams 
593200c79daSDan Williams 	return false;
594200c79daSDan Williams }
595047fc8a1SRoss Zwisler resource_size_t nd_namespace_blk_validate(struct nd_namespace_blk *nsblk);
596*d1c6e08eSDan Williams const uuid_t *nd_dev_to_uuid(struct device *dev);
597004f1afbSDan Williams bool pmem_should_map_pages(struct device *dev);
5984d88a97aSDan Williams #endif /* __ND_H__ */
599