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, 51*3ae3d67bSVishal 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 78bf9bccc1SDan Williams * @alt_name: namespace name supplied in the dimm label 79bf9bccc1SDan Williams * @uuid: namespace name supplied in the dimm label 800e3b0d12SDan Williams * @id: ida allocated id 81bf9bccc1SDan Williams */ 82bf9bccc1SDan Williams struct nd_namespace_pmem { 83bf9bccc1SDan Williams struct nd_namespace_io nsio; 84bf9bccc1SDan Williams char *alt_name; 85bf9bccc1SDan Williams u8 *uuid; 860e3b0d12SDan Williams int id; 87bf9bccc1SDan Williams }; 88bf9bccc1SDan Williams 891b40e09aSDan Williams /** 901b40e09aSDan Williams * struct nd_namespace_blk - namespace for dimm-bounded persistent memory 911b40e09aSDan Williams * @alt_name: namespace name supplied in the dimm label 921b40e09aSDan Williams * @uuid: namespace name supplied in the dimm label 931b40e09aSDan Williams * @id: ida allocated id 941b40e09aSDan Williams * @lbasize: blk namespaces have a native sector size when btt not present 959d90725dSDan Williams * @size: sum of all the resource ranges allocated to this namespace 961b40e09aSDan Williams * @num_resources: number of dpa extents to claim 971b40e09aSDan Williams * @res: discontiguous dpa extents for given dimm 981b40e09aSDan Williams */ 991b40e09aSDan Williams struct nd_namespace_blk { 1008c2f7e86SDan Williams struct nd_namespace_common common; 1011b40e09aSDan Williams char *alt_name; 1021b40e09aSDan Williams u8 *uuid; 1031b40e09aSDan Williams int id; 1041b40e09aSDan Williams unsigned long lbasize; 1059d90725dSDan Williams resource_size_t size; 1061b40e09aSDan Williams int num_resources; 1071b40e09aSDan Williams struct resource **res; 1081b40e09aSDan Williams }; 1091b40e09aSDan Williams 1106ff3e912SDan Williams static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev) 1113d88002eSDan Williams { 1128c2f7e86SDan Williams return container_of(dev, struct nd_namespace_io, common.dev); 1134d88a97aSDan Williams } 1144d88a97aSDan Williams 1156ff3e912SDan Williams static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev) 116bf9bccc1SDan Williams { 117bf9bccc1SDan Williams struct nd_namespace_io *nsio = to_nd_namespace_io(dev); 118bf9bccc1SDan Williams 119bf9bccc1SDan Williams return container_of(nsio, struct nd_namespace_pmem, nsio); 120bf9bccc1SDan Williams } 121bf9bccc1SDan Williams 1226ff3e912SDan Williams static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev) 1231b40e09aSDan Williams { 1248c2f7e86SDan Williams return container_of(dev, struct nd_namespace_blk, common.dev); 1258c2f7e86SDan Williams } 1268c2f7e86SDan Williams 1278c2f7e86SDan Williams /** 1288c2f7e86SDan Williams * nvdimm_read_bytes() - synchronously read bytes from an nvdimm namespace 1298c2f7e86SDan Williams * @ndns: device to read 1308c2f7e86SDan Williams * @offset: namespace-relative starting offset 1318c2f7e86SDan Williams * @buf: buffer to fill 1328c2f7e86SDan Williams * @size: transfer length 1338c2f7e86SDan Williams * 1348c2f7e86SDan Williams * @buf is up-to-date upon return from this routine. 1358c2f7e86SDan Williams */ 1368c2f7e86SDan Williams static inline int nvdimm_read_bytes(struct nd_namespace_common *ndns, 137*3ae3d67bSVishal Verma resource_size_t offset, void *buf, size_t size, 138*3ae3d67bSVishal Verma unsigned long flags) 1398c2f7e86SDan Williams { 140*3ae3d67bSVishal Verma return ndns->rw_bytes(ndns, offset, buf, size, READ, flags); 1418c2f7e86SDan Williams } 1428c2f7e86SDan Williams 1438c2f7e86SDan Williams /** 1448c2f7e86SDan Williams * nvdimm_write_bytes() - synchronously write bytes to an nvdimm namespace 1458c2f7e86SDan Williams * @ndns: device to read 1468c2f7e86SDan Williams * @offset: namespace-relative starting offset 1478c2f7e86SDan Williams * @buf: buffer to drain 1488c2f7e86SDan Williams * @size: transfer length 1498c2f7e86SDan Williams * 1508c2f7e86SDan Williams * NVDIMM Namepaces disks do not implement sectors internally. Depending on 1518c2f7e86SDan Williams * the @ndns, the contents of @buf may be in cpu cache, platform buffers, 1528c2f7e86SDan Williams * or on backing memory media upon return from this routine. Flushing 1538c2f7e86SDan Williams * to media is handled internal to the @ndns driver, if at all. 1548c2f7e86SDan Williams */ 1558c2f7e86SDan Williams static inline int nvdimm_write_bytes(struct nd_namespace_common *ndns, 156*3ae3d67bSVishal Verma resource_size_t offset, void *buf, size_t size, 157*3ae3d67bSVishal Verma unsigned long flags) 1588c2f7e86SDan Williams { 159*3ae3d67bSVishal Verma return ndns->rw_bytes(ndns, offset, buf, size, WRITE, flags); 1601b40e09aSDan Williams } 1611b40e09aSDan Williams 1624d88a97aSDan Williams #define MODULE_ALIAS_ND_DEVICE(type) \ 1634d88a97aSDan Williams MODULE_ALIAS("nd:t" __stringify(type) "*") 1644d88a97aSDan Williams #define ND_DEVICE_MODALIAS_FMT "nd:t%d" 1654d88a97aSDan Williams 16671999466SDan Williams struct nd_region; 16771999466SDan Williams void nvdimm_region_notify(struct nd_region *nd_region, enum nvdimm_event event); 1684d88a97aSDan Williams int __must_check __nd_driver_register(struct nd_device_driver *nd_drv, 1694d88a97aSDan Williams struct module *module, const char *mod_name); 1704d88a97aSDan Williams #define nd_driver_register(driver) \ 1714d88a97aSDan Williams __nd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) 1724d88a97aSDan Williams #endif /* __LINUX_ND_H__ */ 173