xref: /linux/include/linux/nd.h (revision f979b13c3cc51584882bffa32965f34e5afa3b9b)
14d88a97aSDan Williams /*
24d88a97aSDan Williams  * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
34d88a97aSDan Williams  *
44d88a97aSDan Williams  * This program is free software; you can redistribute it and/or modify
54d88a97aSDan Williams  * it under the terms of version 2 of the GNU General Public License as
64d88a97aSDan Williams  * published by the Free Software Foundation.
74d88a97aSDan Williams  *
84d88a97aSDan Williams  * This program is distributed in the hope that it will be useful, but
94d88a97aSDan Williams  * WITHOUT ANY WARRANTY; without even the implied warranty of
104d88a97aSDan Williams  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
114d88a97aSDan Williams  * General Public License for more details.
124d88a97aSDan Williams  */
134d88a97aSDan Williams #ifndef __LINUX_ND_H__
144d88a97aSDan Williams #define __LINUX_ND_H__
158c2f7e86SDan Williams #include <linux/fs.h>
164d88a97aSDan Williams #include <linux/ndctl.h>
174d88a97aSDan Williams #include <linux/device.h>
18200c79daSDan Williams #include <linux/badblocks.h>
194d88a97aSDan Williams 
2071999466SDan Williams enum nvdimm_event {
2171999466SDan Williams 	NVDIMM_REVALIDATE_POISON,
2271999466SDan Williams };
2371999466SDan Williams 
244d88a97aSDan Williams struct nd_device_driver {
254d88a97aSDan Williams 	struct device_driver drv;
264d88a97aSDan Williams 	unsigned long type;
274d88a97aSDan Williams 	int (*probe)(struct device *dev);
284d88a97aSDan Williams 	int (*remove)(struct device *dev);
29476f848aSDan Williams 	void (*shutdown)(struct device *dev);
3071999466SDan Williams 	void (*notify)(struct device *dev, enum nvdimm_event event);
314d88a97aSDan Williams };
324d88a97aSDan Williams 
334d88a97aSDan Williams static inline struct nd_device_driver *to_nd_device_driver(
344d88a97aSDan Williams 		struct device_driver *drv)
354d88a97aSDan Williams {
364d88a97aSDan Williams 	return container_of(drv, struct nd_device_driver, drv);
373d88002eSDan Williams };
383d88002eSDan Williams 
39bf9bccc1SDan Williams /**
408c2f7e86SDan Williams  * struct nd_namespace_common - core infrastructure of a namespace
418c2f7e86SDan Williams  * @force_raw: ignore other personalities for the namespace (e.g. btt)
428c2f7e86SDan Williams  * @dev: device model node
438c2f7e86SDan Williams  * @claim: when set a another personality has taken ownership of the namespace
448c2f7e86SDan Williams  * @rw_bytes: access the raw namespace capacity with byte-aligned transfers
458c2f7e86SDan Williams  */
468c2f7e86SDan Williams struct nd_namespace_common {
478c2f7e86SDan Williams 	int force_raw;
488c2f7e86SDan Williams 	struct device dev;
498c2f7e86SDan Williams 	struct device *claim;
508c2f7e86SDan Williams 	int (*rw_bytes)(struct nd_namespace_common *, resource_size_t offset,
513ae3d67bSVishal Verma 			void *buf, size_t size, int rw, unsigned long flags);
528c2f7e86SDan Williams };
538c2f7e86SDan Williams 
548c2f7e86SDan Williams static inline struct nd_namespace_common *to_ndns(struct device *dev)
558c2f7e86SDan Williams {
568c2f7e86SDan Williams 	return container_of(dev, struct nd_namespace_common, dev);
578c2f7e86SDan Williams }
588c2f7e86SDan Williams 
598c2f7e86SDan Williams /**
60200c79daSDan Williams  * struct nd_namespace_io - device representation of a persistent memory range
61bf9bccc1SDan Williams  * @dev: namespace device created by the nd region driver
62bf9bccc1SDan Williams  * @res: struct resource conversion of a NFIT SPA table
63200c79daSDan Williams  * @size: cached resource_size(@res) for fast path size checks
64200c79daSDan Williams  * @addr: virtual address to access the namespace range
65200c79daSDan Williams  * @bb: badblocks list for the namespace range
66bf9bccc1SDan Williams  */
673d88002eSDan Williams struct nd_namespace_io {
688c2f7e86SDan Williams 	struct nd_namespace_common common;
693d88002eSDan Williams 	struct resource res;
70200c79daSDan Williams 	resource_size_t size;
717a9eb206SDan Williams 	void *addr;
72200c79daSDan Williams 	struct badblocks bb;
733d88002eSDan Williams };
743d88002eSDan Williams 
75bf9bccc1SDan Williams /**
76bf9bccc1SDan Williams  * struct nd_namespace_pmem - namespace device for dimm-backed interleaved memory
77bf9bccc1SDan Williams  * @nsio: device and system physical address range to drive
78*f979b13cSDan Williams  * @lbasize: logical sector size for the namespace in block-device-mode
79bf9bccc1SDan Williams  * @alt_name: namespace name supplied in the dimm label
80bf9bccc1SDan Williams  * @uuid: namespace name supplied in the dimm label
810e3b0d12SDan Williams  * @id: ida allocated id
82bf9bccc1SDan Williams  */
83bf9bccc1SDan Williams struct nd_namespace_pmem {
84bf9bccc1SDan Williams 	struct nd_namespace_io nsio;
85*f979b13cSDan Williams 	unsigned long lbasize;
86bf9bccc1SDan Williams 	char *alt_name;
87bf9bccc1SDan Williams 	u8 *uuid;
880e3b0d12SDan Williams 	int id;
89bf9bccc1SDan Williams };
90bf9bccc1SDan Williams 
911b40e09aSDan Williams /**
921b40e09aSDan Williams  * struct nd_namespace_blk - namespace for dimm-bounded persistent memory
931b40e09aSDan Williams  * @alt_name: namespace name supplied in the dimm label
941b40e09aSDan Williams  * @uuid: namespace name supplied in the dimm label
951b40e09aSDan Williams  * @id: ida allocated id
961b40e09aSDan Williams  * @lbasize: blk namespaces have a native sector size when btt not present
979d90725dSDan Williams  * @size: sum of all the resource ranges allocated to this namespace
981b40e09aSDan Williams  * @num_resources: number of dpa extents to claim
991b40e09aSDan Williams  * @res: discontiguous dpa extents for given dimm
1001b40e09aSDan Williams  */
1011b40e09aSDan Williams struct nd_namespace_blk {
1028c2f7e86SDan Williams 	struct nd_namespace_common common;
1031b40e09aSDan Williams 	char *alt_name;
1041b40e09aSDan Williams 	u8 *uuid;
1051b40e09aSDan Williams 	int id;
1061b40e09aSDan Williams 	unsigned long lbasize;
1079d90725dSDan Williams 	resource_size_t size;
1081b40e09aSDan Williams 	int num_resources;
1091b40e09aSDan Williams 	struct resource **res;
1101b40e09aSDan Williams };
1111b40e09aSDan Williams 
1126ff3e912SDan Williams static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev)
1133d88002eSDan Williams {
1148c2f7e86SDan Williams 	return container_of(dev, struct nd_namespace_io, common.dev);
1154d88a97aSDan Williams }
1164d88a97aSDan Williams 
1176ff3e912SDan Williams static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev)
118bf9bccc1SDan Williams {
119bf9bccc1SDan Williams 	struct nd_namespace_io *nsio = to_nd_namespace_io(dev);
120bf9bccc1SDan Williams 
121bf9bccc1SDan Williams 	return container_of(nsio, struct nd_namespace_pmem, nsio);
122bf9bccc1SDan Williams }
123bf9bccc1SDan Williams 
1246ff3e912SDan Williams static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev)
1251b40e09aSDan Williams {
1268c2f7e86SDan Williams 	return container_of(dev, struct nd_namespace_blk, common.dev);
1278c2f7e86SDan Williams }
1288c2f7e86SDan Williams 
1298c2f7e86SDan Williams /**
1308c2f7e86SDan Williams  * nvdimm_read_bytes() - synchronously read bytes from an nvdimm namespace
1318c2f7e86SDan Williams  * @ndns: device to read
1328c2f7e86SDan Williams  * @offset: namespace-relative starting offset
1338c2f7e86SDan Williams  * @buf: buffer to fill
1348c2f7e86SDan Williams  * @size: transfer length
1358c2f7e86SDan Williams  *
1368c2f7e86SDan Williams  * @buf is up-to-date upon return from this routine.
1378c2f7e86SDan Williams  */
1388c2f7e86SDan Williams static inline int nvdimm_read_bytes(struct nd_namespace_common *ndns,
1393ae3d67bSVishal Verma 		resource_size_t offset, void *buf, size_t size,
1403ae3d67bSVishal Verma 		unsigned long flags)
1418c2f7e86SDan Williams {
1423ae3d67bSVishal Verma 	return ndns->rw_bytes(ndns, offset, buf, size, READ, flags);
1438c2f7e86SDan Williams }
1448c2f7e86SDan Williams 
1458c2f7e86SDan Williams /**
1468c2f7e86SDan Williams  * nvdimm_write_bytes() - synchronously write bytes to an nvdimm namespace
1478c2f7e86SDan Williams  * @ndns: device to read
1488c2f7e86SDan Williams  * @offset: namespace-relative starting offset
1498c2f7e86SDan Williams  * @buf: buffer to drain
1508c2f7e86SDan Williams  * @size: transfer length
1518c2f7e86SDan Williams  *
1528c2f7e86SDan Williams  * NVDIMM Namepaces disks do not implement sectors internally.  Depending on
1538c2f7e86SDan Williams  * the @ndns, the contents of @buf may be in cpu cache, platform buffers,
1548c2f7e86SDan Williams  * or on backing memory media upon return from this routine.  Flushing
1558c2f7e86SDan Williams  * to media is handled internal to the @ndns driver, if at all.
1568c2f7e86SDan Williams  */
1578c2f7e86SDan Williams static inline int nvdimm_write_bytes(struct nd_namespace_common *ndns,
1583ae3d67bSVishal Verma 		resource_size_t offset, void *buf, size_t size,
1593ae3d67bSVishal Verma 		unsigned long flags)
1608c2f7e86SDan Williams {
1613ae3d67bSVishal Verma 	return ndns->rw_bytes(ndns, offset, buf, size, WRITE, flags);
1621b40e09aSDan Williams }
1631b40e09aSDan Williams 
1644d88a97aSDan Williams #define MODULE_ALIAS_ND_DEVICE(type) \
1654d88a97aSDan Williams 	MODULE_ALIAS("nd:t" __stringify(type) "*")
1664d88a97aSDan Williams #define ND_DEVICE_MODALIAS_FMT "nd:t%d"
1674d88a97aSDan Williams 
16871999466SDan Williams struct nd_region;
16971999466SDan Williams void nvdimm_region_notify(struct nd_region *nd_region, enum nvdimm_event event);
1704d88a97aSDan Williams int __must_check __nd_driver_register(struct nd_device_driver *nd_drv,
1714d88a97aSDan Williams 		struct module *module, const char *mod_name);
1724d88a97aSDan Williams #define nd_driver_register(driver) \
1734d88a97aSDan Williams 	__nd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
1744d88a97aSDan Williams #endif /* __LINUX_ND_H__ */
175