diff options
author | Ross Zwisler <ross.zwisler@linux.intel.com> | 2015-06-25 04:21:02 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2015-06-26 11:23:38 -0400 |
commit | 047fc8a1f9a6330eacc80374dff087e20dc2304b (patch) | |
tree | 72ad30740b1770e7c3501d76da55170f05a44a1d /include/linux/libnvdimm.h | |
parent | 5212e11fde4d40fa627668b4f2222d20db488f71 (diff) |
libnvdimm, nfit, nd_blk: driver for BLK-mode access persistent memory
The libnvdimm implementation handles allocating dimm address space (DPA)
between PMEM and BLK mode interfaces. After DPA has been allocated from
a BLK-region to a BLK-namespace the nd_blk driver attaches to handle I/O
as a struct bio based block device. Unlike PMEM, BLK is required to
handle platform specific details like mmio register formats and memory
controller interleave. For this reason the libnvdimm generic nd_blk
driver calls back into the bus provider to carry out the I/O.
This initial implementation handles the BLK interface defined by the
ACPI 6 NFIT [1] and the NVDIMM DSM Interface Example [2] composed from
DCR (dimm control region), BDW (block data window), IDT (interleave
descriptor) NFIT structures and the hardware register format.
[1]: http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf
[2]: http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Boaz Harrosh <boaz@plexistor.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jens Axboe <axboe@fb.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'include/linux/libnvdimm.h')
-rw-r--r-- | include/linux/libnvdimm.h | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 531d99dfac68..7fc1b25bdb5d 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | #ifndef __LIBNVDIMM_H__ | 15 | #ifndef __LIBNVDIMM_H__ |
16 | #define __LIBNVDIMM_H__ | 16 | #define __LIBNVDIMM_H__ |
17 | #include <linux/kernel.h> | ||
17 | #include <linux/sizes.h> | 18 | #include <linux/sizes.h> |
18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
19 | 20 | ||
@@ -89,8 +90,24 @@ struct nd_region_desc { | |||
89 | }; | 90 | }; |
90 | 91 | ||
91 | struct nvdimm_bus; | 92 | struct nvdimm_bus; |
92 | struct device; | ||
93 | struct module; | 93 | struct module; |
94 | struct device; | ||
95 | struct nd_blk_region; | ||
96 | struct nd_blk_region_desc { | ||
97 | int (*enable)(struct nvdimm_bus *nvdimm_bus, struct device *dev); | ||
98 | void (*disable)(struct nvdimm_bus *nvdimm_bus, struct device *dev); | ||
99 | int (*do_io)(struct nd_blk_region *ndbr, resource_size_t dpa, | ||
100 | void *iobuf, u64 len, int rw); | ||
101 | struct nd_region_desc ndr_desc; | ||
102 | }; | ||
103 | |||
104 | static inline struct nd_blk_region_desc *to_blk_region_desc( | ||
105 | struct nd_region_desc *ndr_desc) | ||
106 | { | ||
107 | return container_of(ndr_desc, struct nd_blk_region_desc, ndr_desc); | ||
108 | |||
109 | } | ||
110 | |||
94 | struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, | 111 | struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, |
95 | struct nvdimm_bus_descriptor *nfit_desc, struct module *module); | 112 | struct nvdimm_bus_descriptor *nfit_desc, struct module *module); |
96 | #define nvdimm_bus_register(parent, desc) \ | 113 | #define nvdimm_bus_register(parent, desc) \ |
@@ -99,10 +116,10 @@ void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus); | |||
99 | struct nvdimm_bus *to_nvdimm_bus(struct device *dev); | 116 | struct nvdimm_bus *to_nvdimm_bus(struct device *dev); |
100 | struct nvdimm *to_nvdimm(struct device *dev); | 117 | struct nvdimm *to_nvdimm(struct device *dev); |
101 | struct nd_region *to_nd_region(struct device *dev); | 118 | struct nd_region *to_nd_region(struct device *dev); |
119 | struct nd_blk_region *to_nd_blk_region(struct device *dev); | ||
102 | struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus); | 120 | struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus); |
103 | const char *nvdimm_name(struct nvdimm *nvdimm); | 121 | const char *nvdimm_name(struct nvdimm *nvdimm); |
104 | void *nvdimm_provider_data(struct nvdimm *nvdimm); | 122 | void *nvdimm_provider_data(struct nvdimm *nvdimm); |
105 | void *nd_region_provider_data(struct nd_region *nd_region); | ||
106 | struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, | 123 | struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, |
107 | const struct attribute_group **groups, unsigned long flags, | 124 | const struct attribute_group **groups, unsigned long flags, |
108 | unsigned long *dsm_mask); | 125 | unsigned long *dsm_mask); |
@@ -120,5 +137,11 @@ struct nd_region *nvdimm_blk_region_create(struct nvdimm_bus *nvdimm_bus, | |||
120 | struct nd_region_desc *ndr_desc); | 137 | struct nd_region_desc *ndr_desc); |
121 | struct nd_region *nvdimm_volatile_region_create(struct nvdimm_bus *nvdimm_bus, | 138 | struct nd_region *nvdimm_volatile_region_create(struct nvdimm_bus *nvdimm_bus, |
122 | struct nd_region_desc *ndr_desc); | 139 | struct nd_region_desc *ndr_desc); |
140 | void *nd_region_provider_data(struct nd_region *nd_region); | ||
141 | void *nd_blk_region_provider_data(struct nd_blk_region *ndbr); | ||
142 | void nd_blk_region_set_provider_data(struct nd_blk_region *ndbr, void *data); | ||
143 | struct nvdimm *nd_blk_region_to_dimm(struct nd_blk_region *ndbr); | ||
144 | unsigned int nd_region_acquire_lane(struct nd_region *nd_region); | ||
145 | void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane); | ||
123 | u64 nd_fletcher64(void *addr, size_t len, bool le); | 146 | u64 nd_fletcher64(void *addr, size_t len, bool le); |
124 | #endif /* __LIBNVDIMM_H__ */ | 147 | #endif /* __LIBNVDIMM_H__ */ |