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 __LINUX_ND_H__ 64d88a97aSDan Williams #define __LINUX_ND_H__ 78c2f7e86SDan Williams #include <linux/fs.h> 84d88a97aSDan Williams #include <linux/ndctl.h> 94d88a97aSDan Williams #include <linux/device.h> 10200c79daSDan Williams #include <linux/badblocks.h> 119a61d083SKajol Jain #include <linux/perf_event.h> 12*0fab1ba6SKajol Jain #include <linux/platform_device.h> 134d88a97aSDan Williams 1471999466SDan Williams enum nvdimm_event { 1571999466SDan Williams NVDIMM_REVALIDATE_POISON, 162361db89SDan Williams NVDIMM_REVALIDATE_REGION, 1771999466SDan Williams }; 1871999466SDan Williams 19b3fde74eSDan Williams enum nvdimm_claim_class { 20b3fde74eSDan Williams NVDIMM_CCLASS_NONE, 21b3fde74eSDan Williams NVDIMM_CCLASS_BTT, 2214e49454SVishal Verma NVDIMM_CCLASS_BTT2, 23b3fde74eSDan Williams NVDIMM_CCLASS_PFN, 24b3fde74eSDan Williams NVDIMM_CCLASS_DAX, 25b3fde74eSDan Williams NVDIMM_CCLASS_UNKNOWN, 26b3fde74eSDan Williams }; 27b3fde74eSDan Williams 28*0fab1ba6SKajol Jain #define NVDIMM_EVENT_VAR(_id) event_attr_##_id 29*0fab1ba6SKajol Jain #define NVDIMM_EVENT_PTR(_id) (&event_attr_##_id.attr.attr) 30*0fab1ba6SKajol Jain 31*0fab1ba6SKajol Jain #define NVDIMM_EVENT_ATTR(_name, _id) \ 32*0fab1ba6SKajol Jain PMU_EVENT_ATTR(_name, NVDIMM_EVENT_VAR(_id), _id, \ 33*0fab1ba6SKajol Jain nvdimm_events_sysfs_show) 34*0fab1ba6SKajol Jain 35*0fab1ba6SKajol Jain /* Event attribute array index */ 36*0fab1ba6SKajol Jain #define NVDIMM_PMU_FORMAT_ATTR 0 37*0fab1ba6SKajol Jain #define NVDIMM_PMU_EVENT_ATTR 1 38*0fab1ba6SKajol Jain #define NVDIMM_PMU_CPUMASK_ATTR 2 39*0fab1ba6SKajol Jain #define NVDIMM_PMU_NULL_ATTR 3 40*0fab1ba6SKajol Jain 419a61d083SKajol Jain /** 429a61d083SKajol Jain * struct nvdimm_pmu - data structure for nvdimm perf driver 439a61d083SKajol Jain * @pmu: pmu data structure for nvdimm performance stats. 449a61d083SKajol Jain * @dev: nvdimm device pointer. 459a61d083SKajol Jain * @cpu: designated cpu for counter access. 469a61d083SKajol Jain * @node: node for cpu hotplug notifier link. 479a61d083SKajol Jain * @cpuhp_state: state for cpu hotplug notification. 489a61d083SKajol Jain * @arch_cpumask: cpumask to get designated cpu for counter access. 499a61d083SKajol Jain */ 509a61d083SKajol Jain struct nvdimm_pmu { 519a61d083SKajol Jain struct pmu pmu; 529a61d083SKajol Jain struct device *dev; 539a61d083SKajol Jain int cpu; 549a61d083SKajol Jain struct hlist_node node; 559a61d083SKajol Jain enum cpuhp_state cpuhp_state; 569a61d083SKajol Jain /* cpumask provided by arch/platform specific code */ 579a61d083SKajol Jain struct cpumask arch_cpumask; 589a61d083SKajol Jain }; 599a61d083SKajol Jain 60*0fab1ba6SKajol Jain extern ssize_t nvdimm_events_sysfs_show(struct device *dev, 61*0fab1ba6SKajol Jain struct device_attribute *attr, 62*0fab1ba6SKajol Jain char *page); 63*0fab1ba6SKajol Jain 64*0fab1ba6SKajol Jain int register_nvdimm_pmu(struct nvdimm_pmu *nvdimm, struct platform_device *pdev); 65*0fab1ba6SKajol Jain void unregister_nvdimm_pmu(struct nvdimm_pmu *nd_pmu); 66*0fab1ba6SKajol Jain void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu); 67*0fab1ba6SKajol Jain int perf_pmu_register(struct pmu *pmu, const char *name, int type); 68*0fab1ba6SKajol Jain void perf_pmu_unregister(struct pmu *pmu); 69*0fab1ba6SKajol Jain 704d88a97aSDan Williams struct nd_device_driver { 714d88a97aSDan Williams struct device_driver drv; 724d88a97aSDan Williams unsigned long type; 734d88a97aSDan Williams int (*probe)(struct device *dev); 741f975074SUwe Kleine-König void (*remove)(struct device *dev); 75476f848aSDan Williams void (*shutdown)(struct device *dev); 7671999466SDan Williams void (*notify)(struct device *dev, enum nvdimm_event event); 774d88a97aSDan Williams }; 784d88a97aSDan Williams 794d88a97aSDan Williams static inline struct nd_device_driver *to_nd_device_driver( 804d88a97aSDan Williams struct device_driver *drv) 814d88a97aSDan Williams { 824d88a97aSDan Williams return container_of(drv, struct nd_device_driver, drv); 833d88002eSDan Williams }; 843d88002eSDan Williams 85bf9bccc1SDan Williams /** 868c2f7e86SDan Williams * struct nd_namespace_common - core infrastructure of a namespace 878c2f7e86SDan Williams * @force_raw: ignore other personalities for the namespace (e.g. btt) 888c2f7e86SDan Williams * @dev: device model node 898c2f7e86SDan Williams * @claim: when set a another personality has taken ownership of the namespace 90b3fde74eSDan Williams * @claim_class: restrict claim type to a given class 918c2f7e86SDan Williams * @rw_bytes: access the raw namespace capacity with byte-aligned transfers 928c2f7e86SDan Williams */ 938c2f7e86SDan Williams struct nd_namespace_common { 948c2f7e86SDan Williams int force_raw; 958c2f7e86SDan Williams struct device dev; 968c2f7e86SDan Williams struct device *claim; 97b3fde74eSDan Williams enum nvdimm_claim_class claim_class; 988c2f7e86SDan Williams int (*rw_bytes)(struct nd_namespace_common *, resource_size_t offset, 993ae3d67bSVishal Verma void *buf, size_t size, int rw, unsigned long flags); 1008c2f7e86SDan Williams }; 1018c2f7e86SDan Williams 1028c2f7e86SDan Williams static inline struct nd_namespace_common *to_ndns(struct device *dev) 1038c2f7e86SDan Williams { 1048c2f7e86SDan Williams return container_of(dev, struct nd_namespace_common, dev); 1058c2f7e86SDan Williams } 1068c2f7e86SDan Williams 1078c2f7e86SDan Williams /** 108200c79daSDan Williams * struct nd_namespace_io - device representation of a persistent memory range 109bf9bccc1SDan Williams * @dev: namespace device created by the nd region driver 110bf9bccc1SDan Williams * @res: struct resource conversion of a NFIT SPA table 111200c79daSDan Williams * @size: cached resource_size(@res) for fast path size checks 112200c79daSDan Williams * @addr: virtual address to access the namespace range 113200c79daSDan Williams * @bb: badblocks list for the namespace range 114bf9bccc1SDan Williams */ 1153d88002eSDan Williams struct nd_namespace_io { 1168c2f7e86SDan Williams struct nd_namespace_common common; 1173d88002eSDan Williams struct resource res; 118200c79daSDan Williams resource_size_t size; 1197a9eb206SDan Williams void *addr; 120200c79daSDan Williams struct badblocks bb; 1213d88002eSDan Williams }; 1223d88002eSDan Williams 123bf9bccc1SDan Williams /** 124bf9bccc1SDan Williams * struct nd_namespace_pmem - namespace device for dimm-backed interleaved memory 125bf9bccc1SDan Williams * @nsio: device and system physical address range to drive 126f979b13cSDan Williams * @lbasize: logical sector size for the namespace in block-device-mode 127bf9bccc1SDan Williams * @alt_name: namespace name supplied in the dimm label 128bf9bccc1SDan Williams * @uuid: namespace name supplied in the dimm label 1290e3b0d12SDan Williams * @id: ida allocated id 130bf9bccc1SDan Williams */ 131bf9bccc1SDan Williams struct nd_namespace_pmem { 132bf9bccc1SDan Williams struct nd_namespace_io nsio; 133f979b13cSDan Williams unsigned long lbasize; 134bf9bccc1SDan Williams char *alt_name; 135d1c6e08eSDan Williams uuid_t *uuid; 1360e3b0d12SDan Williams int id; 137bf9bccc1SDan Williams }; 138bf9bccc1SDan Williams 1391b40e09aSDan Williams /** 1401b40e09aSDan Williams * struct nd_namespace_blk - namespace for dimm-bounded persistent memory 1411b40e09aSDan Williams * @alt_name: namespace name supplied in the dimm label 1421b40e09aSDan Williams * @uuid: namespace name supplied in the dimm label 1431b40e09aSDan Williams * @id: ida allocated id 1441b40e09aSDan Williams * @lbasize: blk namespaces have a native sector size when btt not present 1459d90725dSDan Williams * @size: sum of all the resource ranges allocated to this namespace 1461b40e09aSDan Williams * @num_resources: number of dpa extents to claim 1471b40e09aSDan Williams * @res: discontiguous dpa extents for given dimm 1481b40e09aSDan Williams */ 1491b40e09aSDan Williams struct nd_namespace_blk { 1508c2f7e86SDan Williams struct nd_namespace_common common; 1511b40e09aSDan Williams char *alt_name; 152d1c6e08eSDan Williams uuid_t *uuid; 1531b40e09aSDan Williams int id; 1541b40e09aSDan Williams unsigned long lbasize; 1559d90725dSDan Williams resource_size_t size; 1561b40e09aSDan Williams int num_resources; 1571b40e09aSDan Williams struct resource **res; 1581b40e09aSDan Williams }; 1591b40e09aSDan Williams 1606ff3e912SDan Williams static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev) 1613d88002eSDan Williams { 1628c2f7e86SDan Williams return container_of(dev, struct nd_namespace_io, common.dev); 1634d88a97aSDan Williams } 1644d88a97aSDan Williams 1656ff3e912SDan Williams static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev) 166bf9bccc1SDan Williams { 167bf9bccc1SDan Williams struct nd_namespace_io *nsio = to_nd_namespace_io(dev); 168bf9bccc1SDan Williams 169bf9bccc1SDan Williams return container_of(nsio, struct nd_namespace_pmem, nsio); 170bf9bccc1SDan Williams } 171bf9bccc1SDan Williams 1726ff3e912SDan Williams static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev) 1731b40e09aSDan Williams { 1748c2f7e86SDan Williams return container_of(dev, struct nd_namespace_blk, common.dev); 1758c2f7e86SDan Williams } 1768c2f7e86SDan Williams 1778c2f7e86SDan Williams /** 1788c2f7e86SDan Williams * nvdimm_read_bytes() - synchronously read bytes from an nvdimm namespace 1798c2f7e86SDan Williams * @ndns: device to read 1808c2f7e86SDan Williams * @offset: namespace-relative starting offset 1818c2f7e86SDan Williams * @buf: buffer to fill 1828c2f7e86SDan Williams * @size: transfer length 1838c2f7e86SDan Williams * 1848c2f7e86SDan Williams * @buf is up-to-date upon return from this routine. 1858c2f7e86SDan Williams */ 1868c2f7e86SDan Williams static inline int nvdimm_read_bytes(struct nd_namespace_common *ndns, 1873ae3d67bSVishal Verma resource_size_t offset, void *buf, size_t size, 1883ae3d67bSVishal Verma unsigned long flags) 1898c2f7e86SDan Williams { 1903ae3d67bSVishal Verma return ndns->rw_bytes(ndns, offset, buf, size, READ, flags); 1918c2f7e86SDan Williams } 1928c2f7e86SDan Williams 1938c2f7e86SDan Williams /** 1948c2f7e86SDan Williams * nvdimm_write_bytes() - synchronously write bytes to an nvdimm namespace 1952f474149SIra Weiny * @ndns: device to write 1968c2f7e86SDan Williams * @offset: namespace-relative starting offset 1978c2f7e86SDan Williams * @buf: buffer to drain 1988c2f7e86SDan Williams * @size: transfer length 1998c2f7e86SDan Williams * 2008c2f7e86SDan Williams * NVDIMM Namepaces disks do not implement sectors internally. Depending on 2018c2f7e86SDan Williams * the @ndns, the contents of @buf may be in cpu cache, platform buffers, 2028c2f7e86SDan Williams * or on backing memory media upon return from this routine. Flushing 2038c2f7e86SDan Williams * to media is handled internal to the @ndns driver, if at all. 2048c2f7e86SDan Williams */ 2058c2f7e86SDan Williams static inline int nvdimm_write_bytes(struct nd_namespace_common *ndns, 2063ae3d67bSVishal Verma resource_size_t offset, void *buf, size_t size, 2073ae3d67bSVishal Verma unsigned long flags) 2088c2f7e86SDan Williams { 2093ae3d67bSVishal Verma return ndns->rw_bytes(ndns, offset, buf, size, WRITE, flags); 2101b40e09aSDan Williams } 2111b40e09aSDan Williams 2124d88a97aSDan Williams #define MODULE_ALIAS_ND_DEVICE(type) \ 2134d88a97aSDan Williams MODULE_ALIAS("nd:t" __stringify(type) "*") 2144d88a97aSDan Williams #define ND_DEVICE_MODALIAS_FMT "nd:t%d" 2154d88a97aSDan Williams 21671999466SDan Williams struct nd_region; 21771999466SDan Williams void nvdimm_region_notify(struct nd_region *nd_region, enum nvdimm_event event); 2184d88a97aSDan Williams int __must_check __nd_driver_register(struct nd_device_driver *nd_drv, 2194d88a97aSDan Williams struct module *module, const char *mod_name); 22071cfdd0bSJohannes Thumshirn static inline void nd_driver_unregister(struct nd_device_driver *drv) 22171cfdd0bSJohannes Thumshirn { 22271cfdd0bSJohannes Thumshirn driver_unregister(&drv->drv); 22371cfdd0bSJohannes Thumshirn } 2244d88a97aSDan Williams #define nd_driver_register(driver) \ 2254d88a97aSDan Williams __nd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) 22671cfdd0bSJohannes Thumshirn #define module_nd_driver(driver) \ 22771cfdd0bSJohannes Thumshirn module_driver(driver, nd_driver_register, nd_driver_unregister) 2284d88a97aSDan Williams #endif /* __LINUX_ND_H__ */ 229