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