linux/include/linux/nd.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
   4 */
   5#ifndef __LINUX_ND_H__
   6#define __LINUX_ND_H__
   7#include <linux/fs.h>
   8#include <linux/ndctl.h>
   9#include <linux/device.h>
  10#include <linux/badblocks.h>
  11
  12enum nvdimm_event {
  13        NVDIMM_REVALIDATE_POISON,
  14        NVDIMM_REVALIDATE_REGION,
  15};
  16
  17enum nvdimm_claim_class {
  18        NVDIMM_CCLASS_NONE,
  19        NVDIMM_CCLASS_BTT,
  20        NVDIMM_CCLASS_BTT2,
  21        NVDIMM_CCLASS_PFN,
  22        NVDIMM_CCLASS_DAX,
  23        NVDIMM_CCLASS_UNKNOWN,
  24};
  25
  26struct nd_device_driver {
  27        struct device_driver drv;
  28        unsigned long type;
  29        int (*probe)(struct device *dev);
  30        void (*remove)(struct device *dev);
  31        void (*shutdown)(struct device *dev);
  32        void (*notify)(struct device *dev, enum nvdimm_event event);
  33};
  34
  35static inline struct nd_device_driver *to_nd_device_driver(
  36                struct device_driver *drv)
  37{
  38        return container_of(drv, struct nd_device_driver, drv);
  39};
  40
  41/**
  42 * struct nd_namespace_common - core infrastructure of a namespace
  43 * @force_raw: ignore other personalities for the namespace (e.g. btt)
  44 * @dev: device model node
  45 * @claim: when set a another personality has taken ownership of the namespace
  46 * @claim_class: restrict claim type to a given class
  47 * @rw_bytes: access the raw namespace capacity with byte-aligned transfers
  48 */
  49struct nd_namespace_common {
  50        int force_raw;
  51        struct device dev;
  52        struct device *claim;
  53        enum nvdimm_claim_class claim_class;
  54        int (*rw_bytes)(struct nd_namespace_common *, resource_size_t offset,
  55                        void *buf, size_t size, int rw, unsigned long flags);
  56};
  57
  58static inline struct nd_namespace_common *to_ndns(struct device *dev)
  59{
  60        return container_of(dev, struct nd_namespace_common, dev);
  61}
  62
  63/**
  64 * struct nd_namespace_io - device representation of a persistent memory range
  65 * @dev: namespace device created by the nd region driver
  66 * @res: struct resource conversion of a NFIT SPA table
  67 * @size: cached resource_size(@res) for fast path size checks
  68 * @addr: virtual address to access the namespace range
  69 * @bb: badblocks list for the namespace range
  70 */
  71struct nd_namespace_io {
  72        struct nd_namespace_common common;
  73        struct resource res;
  74        resource_size_t size;
  75        void *addr;
  76        struct badblocks bb;
  77};
  78
  79/**
  80 * struct nd_namespace_pmem - namespace device for dimm-backed interleaved memory
  81 * @nsio: device and system physical address range to drive
  82 * @lbasize: logical sector size for the namespace in block-device-mode
  83 * @alt_name: namespace name supplied in the dimm label
  84 * @uuid: namespace name supplied in the dimm label
  85 * @id: ida allocated id
  86 */
  87struct nd_namespace_pmem {
  88        struct nd_namespace_io nsio;
  89        unsigned long lbasize;
  90        char *alt_name;
  91        u8 *uuid;
  92        int id;
  93};
  94
  95/**
  96 * struct nd_namespace_blk - namespace for dimm-bounded persistent memory
  97 * @alt_name: namespace name supplied in the dimm label
  98 * @uuid: namespace name supplied in the dimm label
  99 * @id: ida allocated id
 100 * @lbasize: blk namespaces have a native sector size when btt not present
 101 * @size: sum of all the resource ranges allocated to this namespace
 102 * @num_resources: number of dpa extents to claim
 103 * @res: discontiguous dpa extents for given dimm
 104 */
 105struct nd_namespace_blk {
 106        struct nd_namespace_common common;
 107        char *alt_name;
 108        u8 *uuid;
 109        int id;
 110        unsigned long lbasize;
 111        resource_size_t size;
 112        int num_resources;
 113        struct resource **res;
 114};
 115
 116static inline struct nd_namespace_io *to_nd_namespace_io(const struct device *dev)
 117{
 118        return container_of(dev, struct nd_namespace_io, common.dev);
 119}
 120
 121static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device *dev)
 122{
 123        struct nd_namespace_io *nsio = to_nd_namespace_io(dev);
 124
 125        return container_of(nsio, struct nd_namespace_pmem, nsio);
 126}
 127
 128static inline struct nd_namespace_blk *to_nd_namespace_blk(const struct device *dev)
 129{
 130        return container_of(dev, struct nd_namespace_blk, common.dev);
 131}
 132
 133/**
 134 * nvdimm_read_bytes() - synchronously read bytes from an nvdimm namespace
 135 * @ndns: device to read
 136 * @offset: namespace-relative starting offset
 137 * @buf: buffer to fill
 138 * @size: transfer length
 139 *
 140 * @buf is up-to-date upon return from this routine.
 141 */
 142static inline int nvdimm_read_bytes(struct nd_namespace_common *ndns,
 143                resource_size_t offset, void *buf, size_t size,
 144                unsigned long flags)
 145{
 146        return ndns->rw_bytes(ndns, offset, buf, size, READ, flags);
 147}
 148
 149/**
 150 * nvdimm_write_bytes() - synchronously write bytes to an nvdimm namespace
 151 * @ndns: device to write
 152 * @offset: namespace-relative starting offset
 153 * @buf: buffer to drain
 154 * @size: transfer length
 155 *
 156 * NVDIMM Namepaces disks do not implement sectors internally.  Depending on
 157 * the @ndns, the contents of @buf may be in cpu cache, platform buffers,
 158 * or on backing memory media upon return from this routine.  Flushing
 159 * to media is handled internal to the @ndns driver, if at all.
 160 */
 161static inline int nvdimm_write_bytes(struct nd_namespace_common *ndns,
 162                resource_size_t offset, void *buf, size_t size,
 163                unsigned long flags)
 164{
 165        return ndns->rw_bytes(ndns, offset, buf, size, WRITE, flags);
 166}
 167
 168#define MODULE_ALIAS_ND_DEVICE(type) \
 169        MODULE_ALIAS("nd:t" __stringify(type) "*")
 170#define ND_DEVICE_MODALIAS_FMT "nd:t%d"
 171
 172struct nd_region;
 173void nvdimm_region_notify(struct nd_region *nd_region, enum nvdimm_event event);
 174int __must_check __nd_driver_register(struct nd_device_driver *nd_drv,
 175                struct module *module, const char *mod_name);
 176static inline void nd_driver_unregister(struct nd_device_driver *drv)
 177{
 178        driver_unregister(&drv->drv);
 179}
 180#define nd_driver_register(driver) \
 181        __nd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
 182#define module_nd_driver(driver) \
 183        module_driver(driver, nd_driver_register, nd_driver_unregister)
 184#endif /* __LINUX_ND_H__ */
 185