Blame view

drivers/nvdimm/nd.h 7.72 KB
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
   * published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   */
  #ifndef __ND_H__
  #define __ND_H__
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
15
  #include <linux/libnvdimm.h>
f0dc089ce   Dan Williams   libnvdimm: enable...
16
  #include <linux/blkdev.h>
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
17
18
19
  #include <linux/device.h>
  #include <linux/mutex.h>
  #include <linux/ndctl.h>
bf9bccc14   Dan Williams   libnvdimm: pmem l...
20
  #include <linux/types.h>
4a826c83d   Dan Williams   libnvdimm: namesp...
21
  #include "label.h"
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
22

8c2f7e865   Dan Williams   libnvdimm: infras...
23
  enum {
5212e11fd   Vishal Verma   nd_btt: atomic se...
24
25
26
27
28
29
  	/*
  	 * Limits the maximum number of block apertures a dimm can
  	 * support and is an input to the geometry/on-disk-format of a
  	 * BTT instance
  	 */
  	ND_MAX_LANES = 256,
8c2f7e865   Dan Williams   libnvdimm: infras...
30
  	SECTOR_SHIFT = 9,
fcae69573   Vishal Verma   libnvdimm, blk: a...
31
  	INT_LBASIZE_ALIGNMENT = 64,
e1455744b   Dan Williams   libnvdimm, pfn: '...
32
33
34
35
36
37
38
  #if IS_ENABLED(CONFIG_NVDIMM_PFN)
  	ND_PFN_ALIGN = PAGES_PER_SECTION * PAGE_SIZE,
  	ND_PFN_MASK = ND_PFN_ALIGN - 1,
  #else
  	ND_PFN_ALIGN = 0,
  	ND_PFN_MASK = 0,
  #endif
8c2f7e865   Dan Williams   libnvdimm: infras...
39
  };
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
40
41
  struct nvdimm_drvdata {
  	struct device *dev;
4a826c83d   Dan Williams   libnvdimm: namesp...
42
  	int nsindex_size;
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
43
44
  	struct nd_cmd_get_config_size nsarea;
  	void *data;
4a826c83d   Dan Williams   libnvdimm: namesp...
45
46
  	int ns_current, ns_next;
  	struct resource dpa;
bf9bccc14   Dan Williams   libnvdimm: pmem l...
47
  	struct kref kref;
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
48
  };
3d88002e4   Dan Williams   libnvdimm: suppor...
49
50
51
52
  struct nd_region_namespaces {
  	int count;
  	int active;
  };
4a826c83d   Dan Williams   libnvdimm: namesp...
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  static inline struct nd_namespace_index *to_namespace_index(
  		struct nvdimm_drvdata *ndd, int i)
  {
  	if (i < 0)
  		return NULL;
  
  	return ndd->data + sizeof_namespace_index(ndd) * i;
  }
  
  static inline struct nd_namespace_index *to_current_namespace_index(
  		struct nvdimm_drvdata *ndd)
  {
  	return to_namespace_index(ndd, ndd->ns_current);
  }
  
  static inline struct nd_namespace_index *to_next_namespace_index(
  		struct nvdimm_drvdata *ndd)
  {
  	return to_namespace_index(ndd, ndd->ns_next);
  }
  
  #define nd_dbg_dpa(r, d, res, fmt, arg...) \
  	dev_dbg((r) ? &(r)->dev : (d)->dev, "%s: %.13s: %#llx @ %#llx " fmt, \
  		(r) ? dev_name((d)->dev) : "", res ? res->name : "null", \
  		(unsigned long long) (res ? resource_size(res) : 0), \
  		(unsigned long long) (res ? res->start : 0), ##arg)
bf9bccc14   Dan Williams   libnvdimm: pmem l...
79
80
81
82
83
  #define for_each_label(l, label, labels) \
  	for (l = 0; (label = labels ? labels[l] : NULL); l++)
  
  #define for_each_dpa_resource(ndd, res) \
  	for (res = (ndd)->dpa.child; res; res = res->sibling)
4a826c83d   Dan Williams   libnvdimm: namesp...
84
85
86
  #define for_each_dpa_resource_safe(ndd, res, next) \
  	for (res = (ndd)->dpa.child, next = res ? res->sibling : NULL; \
  			res; res = next, next = next ? next->sibling : NULL)
5212e11fd   Vishal Verma   nd_btt: atomic se...
87
88
89
90
  struct nd_percpu_lane {
  	int count;
  	spinlock_t lock;
  };
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
91
92
  struct nd_region {
  	struct device dev;
1b40e09a1   Dan Williams   libnvdimm: blk la...
93
  	struct ida ns_ida;
8c2f7e865   Dan Williams   libnvdimm: infras...
94
  	struct ida btt_ida;
e1455744b   Dan Williams   libnvdimm, pfn: '...
95
  	struct ida pfn_ida;
004f1afbe   Dan Williams   libnvdimm, pmem: ...
96
  	unsigned long flags;
bf9bccc14   Dan Williams   libnvdimm: pmem l...
97
  	struct device *ns_seed;
8c2f7e865   Dan Williams   libnvdimm: infras...
98
  	struct device *btt_seed;
e1455744b   Dan Williams   libnvdimm, pfn: '...
99
  	struct device *pfn_seed;
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
100
101
102
  	u16 ndr_mappings;
  	u64 ndr_size;
  	u64 ndr_start;
41d7a6d63   Toshi Kani   libnvdimm: Set nu...
103
  	int id, num_lanes, ro, numa_node;
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
104
  	void *provider_data;
eaf961536   Dan Williams   libnvdimm, nfit: ...
105
  	struct nd_interleave_set *nd_set;
5212e11fd   Vishal Verma   nd_btt: atomic se...
106
  	struct nd_percpu_lane __percpu *lane;
1f7df6f88   Dan Williams   libnvdimm, nfit: ...
107
108
  	struct nd_mapping mapping[0];
  };
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
109
110
111
112
113
114
115
116
  struct nd_blk_region {
  	int (*enable)(struct nvdimm_bus *nvdimm_bus, struct device *dev);
  	void (*disable)(struct nvdimm_bus *nvdimm_bus, struct device *dev);
  	int (*do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
  			void *iobuf, u64 len, int rw);
  	void *blk_provider_data;
  	struct nd_region nd_region;
  };
4a826c83d   Dan Williams   libnvdimm: namesp...
117
118
119
120
121
122
123
124
125
  /*
   * Lookup next in the repeating sequence of 01, 10, and 11.
   */
  static inline unsigned nd_inc_seq(unsigned seq)
  {
  	static const unsigned next[] = { 0, 2, 3, 1 };
  
  	return next[seq & 3];
  }
f524bf271   Dan Williams   libnvdimm: write ...
126

5212e11fd   Vishal Verma   nd_btt: atomic se...
127
  struct btt;
8c2f7e865   Dan Williams   libnvdimm: infras...
128
129
130
  struct nd_btt {
  	struct device dev;
  	struct nd_namespace_common *ndns;
5212e11fd   Vishal Verma   nd_btt: atomic se...
131
  	struct btt *btt;
8c2f7e865   Dan Williams   libnvdimm: infras...
132
133
134
135
  	unsigned long lbasize;
  	u8 *uuid;
  	int id;
  };
e1455744b   Dan Williams   libnvdimm, pfn: '...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  enum nd_pfn_mode {
  	PFN_MODE_NONE,
  	PFN_MODE_RAM,
  	PFN_MODE_PMEM,
  };
  
  struct nd_pfn {
  	int id;
  	u8 *uuid;
  	struct device dev;
  	unsigned long npfns;
  	enum nd_pfn_mode mode;
  	struct nd_pfn_sb *pfn_sb;
  	struct nd_namespace_common *ndns;
  };
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
151
152
153
154
  enum nd_async_mode {
  	ND_SYNC,
  	ND_ASYNC,
  };
41cd8b70c   Vishal Verma   libnvdimm, btt: a...
155
  int nd_integrity_init(struct gendisk *disk, unsigned long meta_size);
bf9bccc14   Dan Williams   libnvdimm: pmem l...
156
  void wait_nvdimm_bus_probe_idle(struct device *dev);
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
157
158
  void nd_device_register(struct device *dev);
  void nd_device_unregister(struct device *dev, enum nd_async_mode mode);
bf9bccc14   Dan Williams   libnvdimm: pmem l...
159
160
  int nd_uuid_store(struct device *dev, u8 **uuid_out, const char *buf,
  		size_t len);
1b40e09a1   Dan Williams   libnvdimm: blk la...
161
162
163
164
  ssize_t nd_sector_size_show(unsigned long current_lbasize,
  		const unsigned long *supported, char *buf);
  ssize_t nd_sector_size_store(struct device *dev, const char *buf,
  		unsigned long *current_lbasize, const unsigned long *supported);
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
165
  int __init nvdimm_init(void);
3d88002e4   Dan Williams   libnvdimm: suppor...
166
  int __init nd_region_init(void);
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
167
  void nvdimm_exit(void);
3d88002e4   Dan Williams   libnvdimm: suppor...
168
  void nd_region_exit(void);
bf9bccc14   Dan Williams   libnvdimm: pmem l...
169
170
  struct nvdimm;
  struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping);
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
171
172
  int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd);
  int nvdimm_init_config_data(struct nvdimm_drvdata *ndd);
f524bf271   Dan Williams   libnvdimm: write ...
173
174
  int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
  		void *buf, size_t len);
8c2f7e865   Dan Williams   libnvdimm: infras...
175
  struct nd_btt *to_nd_btt(struct device *dev);
e1455744b   Dan Williams   libnvdimm, pfn: '...
176
177
178
179
180
181
182
  
  struct nd_gen_sb {
  	char reserved[SZ_4K - 8];
  	__le64 checksum;
  };
  
  u64 nd_sb_checksum(struct nd_gen_sb *sb);
8c2f7e865   Dan Williams   libnvdimm: infras...
183
184
185
186
187
  #if IS_ENABLED(CONFIG_BTT)
  int nd_btt_probe(struct nd_namespace_common *ndns, void *drvdata);
  bool is_nd_btt(struct device *dev);
  struct device *nd_btt_create(struct nd_region *nd_region);
  #else
f6ef5a2a5   Randy Dunlap   nvdimm: fix inlin...
188
  static inline int nd_btt_probe(struct nd_namespace_common *ndns, void *drvdata)
8c2f7e865   Dan Williams   libnvdimm: infras...
189
190
191
192
193
194
195
196
197
198
199
200
201
  {
  	return -ENODEV;
  }
  
  static inline bool is_nd_btt(struct device *dev)
  {
  	return false;
  }
  
  static inline struct device *nd_btt_create(struct nd_region *nd_region)
  {
  	return NULL;
  }
e1455744b   Dan Williams   libnvdimm, pfn: '...
202
  #endif
8c2f7e865   Dan Williams   libnvdimm: infras...
203

e1455744b   Dan Williams   libnvdimm, pfn: '...
204
205
206
207
208
  struct nd_pfn *to_nd_pfn(struct device *dev);
  #if IS_ENABLED(CONFIG_NVDIMM_PFN)
  int nd_pfn_probe(struct nd_namespace_common *ndns, void *drvdata);
  bool is_nd_pfn(struct device *dev);
  struct device *nd_pfn_create(struct nd_region *nd_region);
32ab0a3f5   Dan Williams   libnvdimm, pmem: ...
209
  int nd_pfn_validate(struct nd_pfn *nd_pfn);
e1455744b   Dan Williams   libnvdimm, pfn: '...
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
  #else
  static inline int nd_pfn_probe(struct nd_namespace_common *ndns, void *drvdata)
  {
  	return -ENODEV;
  }
  
  static inline bool is_nd_pfn(struct device *dev)
  {
  	return false;
  }
  
  static inline struct device *nd_pfn_create(struct nd_region *nd_region)
  {
  	return NULL;
  }
32ab0a3f5   Dan Williams   libnvdimm, pmem: ...
225
226
227
228
229
  
  static inline int nd_pfn_validate(struct nd_pfn *nd_pfn)
  {
  	return -ENODEV;
  }
8c2f7e865   Dan Williams   libnvdimm: infras...
230
  #endif
e1455744b   Dan Williams   libnvdimm, pfn: '...
231

3d88002e4   Dan Williams   libnvdimm: suppor...
232
233
234
  struct nd_region *to_nd_region(struct device *dev);
  int nd_region_to_nstype(struct nd_region *nd_region);
  int nd_region_register_namespaces(struct nd_region *nd_region, int *err);
bf9bccc14   Dan Williams   libnvdimm: pmem l...
235
  u64 nd_region_interleave_set_cookie(struct nd_region *nd_region);
3d88002e4   Dan Williams   libnvdimm: suppor...
236
237
238
  void nvdimm_bus_lock(struct device *dev);
  void nvdimm_bus_unlock(struct device *dev);
  bool is_nvdimm_bus_locked(struct device *dev);
581388209   Dan Williams   libnvdimm, nfit: ...
239
  int nvdimm_revalidate_disk(struct gendisk *disk);
bf9bccc14   Dan Williams   libnvdimm: pmem l...
240
241
  void nvdimm_drvdata_release(struct kref *kref);
  void put_ndd(struct nvdimm_drvdata *ndd);
4a826c83d   Dan Williams   libnvdimm: namesp...
242
243
244
245
246
  int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd);
  void nvdimm_free_dpa(struct nvdimm_drvdata *ndd, struct resource *res);
  struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd,
  		struct nd_label_id *label_id, resource_size_t start,
  		resource_size_t n);
8c2f7e865   Dan Williams   libnvdimm: infras...
247
248
  resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns);
  struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev);
5212e11fd   Vishal Verma   nd_btt: atomic se...
249
250
251
252
  int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns);
  int nvdimm_namespace_detach_btt(struct nd_namespace_common *ndns);
  const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,
  		char *name);
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
253
  int nd_blk_region_init(struct nd_region *nd_region);
f0dc089ce   Dan Williams   libnvdimm: enable...
254
255
256
257
258
259
260
261
262
263
264
265
  void __nd_iostat_start(struct bio *bio, unsigned long *start);
  static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
  {
  	struct gendisk *disk = bio->bi_bdev->bd_disk;
  
  	if (!blk_queue_io_stat(disk->queue))
  		return false;
  
  	__nd_iostat_start(bio, start);
  	return true;
  }
  void nd_iostat_end(struct bio *bio, unsigned long start);
047fc8a1f   Ross Zwisler   libnvdimm, nfit, ...
266
  resource_size_t nd_namespace_blk_validate(struct nd_namespace_blk *nsblk);
6ec689542   Vishal Verma   libnvdimm, btt: w...
267
  const u8 *nd_dev_to_uuid(struct device *dev);
004f1afbe   Dan Williams   libnvdimm, pmem: ...
268
  bool pmem_should_map_pages(struct device *dev);
4d88a97aa   Dan Williams   libnvdimm, nvdimm...
269
  #endif /* __ND_H__ */