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