.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * libnvdimm - Non-volatile-memory Devices Subsystem |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of version 2 of the GNU General Public License as |
---|
8 | | - * published by the Free Software Foundation. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, but |
---|
11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
13 | | - * General Public License for more details. |
---|
14 | 6 | */ |
---|
15 | 7 | #ifndef __LIBNVDIMM_H__ |
---|
16 | 8 | #define __LIBNVDIMM_H__ |
---|
.. | .. |
---|
39 | 31 | NDD_UNARMED = 1, |
---|
40 | 32 | /* locked memory devices should not be accessed */ |
---|
41 | 33 | NDD_LOCKED = 2, |
---|
| 34 | + /* memory under security wipes should not be accessed */ |
---|
| 35 | + NDD_SECURITY_OVERWRITE = 3, |
---|
| 36 | + /* tracking whether or not there is a pending device reference */ |
---|
| 37 | + NDD_WORK_PENDING = 4, |
---|
| 38 | + /* ignore / filter NSLABEL_FLAG_LOCAL for this DIMM, i.e. no aliasing */ |
---|
| 39 | + NDD_NOBLK = 5, |
---|
| 40 | + /* dimm supports namespace labels */ |
---|
| 41 | + NDD_LABELING = 6, |
---|
42 | 42 | |
---|
43 | 43 | /* need to set a limit somewhere, but yes, this is likely overkill */ |
---|
44 | 44 | ND_IOCTL_MAX_BUFLEN = SZ_4M, |
---|
.. | .. |
---|
67 | 67 | DPA_RESOURCE_ADJUSTED = 1 << 0, |
---|
68 | 68 | }; |
---|
69 | 69 | |
---|
70 | | -extern struct attribute_group nvdimm_bus_attribute_group; |
---|
71 | | -extern struct attribute_group nvdimm_attribute_group; |
---|
72 | | -extern struct attribute_group nd_device_attribute_group; |
---|
73 | | -extern struct attribute_group nd_numa_attribute_group; |
---|
74 | | -extern struct attribute_group nd_region_attribute_group; |
---|
75 | | -extern struct attribute_group nd_mapping_attribute_group; |
---|
76 | | - |
---|
77 | 70 | struct nvdimm; |
---|
78 | 71 | struct nvdimm_bus_descriptor; |
---|
79 | 72 | typedef int (*ndctl_fn)(struct nvdimm_bus_descriptor *nd_desc, |
---|
.. | .. |
---|
83 | 76 | struct device_node; |
---|
84 | 77 | struct nvdimm_bus_descriptor { |
---|
85 | 78 | const struct attribute_group **attr_groups; |
---|
86 | | - unsigned long bus_dsm_mask; |
---|
87 | 79 | unsigned long cmd_mask; |
---|
| 80 | + unsigned long dimm_family_mask; |
---|
| 81 | + unsigned long bus_family_mask; |
---|
88 | 82 | struct module *module; |
---|
89 | 83 | char *provider_name; |
---|
90 | 84 | struct device_node *of_node; |
---|
91 | 85 | ndctl_fn ndctl; |
---|
92 | 86 | int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc); |
---|
93 | 87 | int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc, |
---|
94 | | - struct nvdimm *nvdimm, unsigned int cmd); |
---|
| 88 | + struct nvdimm *nvdimm, unsigned int cmd, void *data); |
---|
| 89 | + const struct nvdimm_bus_fw_ops *fw_ops; |
---|
95 | 90 | }; |
---|
96 | 91 | |
---|
97 | 92 | struct nd_cmd_desc { |
---|
.. | .. |
---|
129 | 124 | void *provider_data; |
---|
130 | 125 | int num_lanes; |
---|
131 | 126 | int numa_node; |
---|
| 127 | + int target_node; |
---|
132 | 128 | unsigned long flags; |
---|
133 | 129 | struct device_node *of_node; |
---|
134 | 130 | int (*flush)(struct nd_region *nd_region, struct bio *bio); |
---|
.. | .. |
---|
161 | 157 | |
---|
162 | 158 | } |
---|
163 | 159 | |
---|
| 160 | +/* |
---|
| 161 | + * Note that separate bits for locked + unlocked are defined so that |
---|
| 162 | + * 'flags == 0' corresponds to an error / not-supported state. |
---|
| 163 | + */ |
---|
| 164 | +enum nvdimm_security_bits { |
---|
| 165 | + NVDIMM_SECURITY_DISABLED, |
---|
| 166 | + NVDIMM_SECURITY_UNLOCKED, |
---|
| 167 | + NVDIMM_SECURITY_LOCKED, |
---|
| 168 | + NVDIMM_SECURITY_FROZEN, |
---|
| 169 | + NVDIMM_SECURITY_OVERWRITE, |
---|
| 170 | +}; |
---|
| 171 | + |
---|
| 172 | +#define NVDIMM_PASSPHRASE_LEN 32 |
---|
| 173 | +#define NVDIMM_KEY_DESC_LEN 22 |
---|
| 174 | + |
---|
| 175 | +struct nvdimm_key_data { |
---|
| 176 | + u8 data[NVDIMM_PASSPHRASE_LEN]; |
---|
| 177 | +}; |
---|
| 178 | + |
---|
| 179 | +enum nvdimm_passphrase_type { |
---|
| 180 | + NVDIMM_USER, |
---|
| 181 | + NVDIMM_MASTER, |
---|
| 182 | +}; |
---|
| 183 | + |
---|
| 184 | +struct nvdimm_security_ops { |
---|
| 185 | + unsigned long (*get_flags)(struct nvdimm *nvdimm, |
---|
| 186 | + enum nvdimm_passphrase_type pass_type); |
---|
| 187 | + int (*freeze)(struct nvdimm *nvdimm); |
---|
| 188 | + int (*change_key)(struct nvdimm *nvdimm, |
---|
| 189 | + const struct nvdimm_key_data *old_data, |
---|
| 190 | + const struct nvdimm_key_data *new_data, |
---|
| 191 | + enum nvdimm_passphrase_type pass_type); |
---|
| 192 | + int (*unlock)(struct nvdimm *nvdimm, |
---|
| 193 | + const struct nvdimm_key_data *key_data); |
---|
| 194 | + int (*disable)(struct nvdimm *nvdimm, |
---|
| 195 | + const struct nvdimm_key_data *key_data); |
---|
| 196 | + int (*erase)(struct nvdimm *nvdimm, |
---|
| 197 | + const struct nvdimm_key_data *key_data, |
---|
| 198 | + enum nvdimm_passphrase_type pass_type); |
---|
| 199 | + int (*overwrite)(struct nvdimm *nvdimm, |
---|
| 200 | + const struct nvdimm_key_data *key_data); |
---|
| 201 | + int (*query_overwrite)(struct nvdimm *nvdimm); |
---|
| 202 | +}; |
---|
| 203 | + |
---|
| 204 | +enum nvdimm_fwa_state { |
---|
| 205 | + NVDIMM_FWA_INVALID, |
---|
| 206 | + NVDIMM_FWA_IDLE, |
---|
| 207 | + NVDIMM_FWA_ARMED, |
---|
| 208 | + NVDIMM_FWA_BUSY, |
---|
| 209 | + NVDIMM_FWA_ARM_OVERFLOW, |
---|
| 210 | +}; |
---|
| 211 | + |
---|
| 212 | +enum nvdimm_fwa_trigger { |
---|
| 213 | + NVDIMM_FWA_ARM, |
---|
| 214 | + NVDIMM_FWA_DISARM, |
---|
| 215 | +}; |
---|
| 216 | + |
---|
| 217 | +enum nvdimm_fwa_capability { |
---|
| 218 | + NVDIMM_FWA_CAP_INVALID, |
---|
| 219 | + NVDIMM_FWA_CAP_NONE, |
---|
| 220 | + NVDIMM_FWA_CAP_QUIESCE, |
---|
| 221 | + NVDIMM_FWA_CAP_LIVE, |
---|
| 222 | +}; |
---|
| 223 | + |
---|
| 224 | +enum nvdimm_fwa_result { |
---|
| 225 | + NVDIMM_FWA_RESULT_INVALID, |
---|
| 226 | + NVDIMM_FWA_RESULT_NONE, |
---|
| 227 | + NVDIMM_FWA_RESULT_SUCCESS, |
---|
| 228 | + NVDIMM_FWA_RESULT_NOTSTAGED, |
---|
| 229 | + NVDIMM_FWA_RESULT_NEEDRESET, |
---|
| 230 | + NVDIMM_FWA_RESULT_FAIL, |
---|
| 231 | +}; |
---|
| 232 | + |
---|
| 233 | +struct nvdimm_bus_fw_ops { |
---|
| 234 | + enum nvdimm_fwa_state (*activate_state) |
---|
| 235 | + (struct nvdimm_bus_descriptor *nd_desc); |
---|
| 236 | + enum nvdimm_fwa_capability (*capability) |
---|
| 237 | + (struct nvdimm_bus_descriptor *nd_desc); |
---|
| 238 | + int (*activate)(struct nvdimm_bus_descriptor *nd_desc); |
---|
| 239 | +}; |
---|
| 240 | + |
---|
| 241 | +struct nvdimm_fw_ops { |
---|
| 242 | + enum nvdimm_fwa_state (*activate_state)(struct nvdimm *nvdimm); |
---|
| 243 | + enum nvdimm_fwa_result (*activate_result)(struct nvdimm *nvdimm); |
---|
| 244 | + int (*arm)(struct nvdimm *nvdimm, enum nvdimm_fwa_trigger arg); |
---|
| 245 | +}; |
---|
| 246 | + |
---|
164 | 247 | void badrange_init(struct badrange *badrange); |
---|
165 | 248 | int badrange_add(struct badrange *badrange, u64 addr, u64 length); |
---|
166 | 249 | void badrange_forget(struct badrange *badrange, phys_addr_t start, |
---|
.. | .. |
---|
171 | 254 | struct nvdimm_bus_descriptor *nfit_desc); |
---|
172 | 255 | void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus); |
---|
173 | 256 | struct nvdimm_bus *to_nvdimm_bus(struct device *dev); |
---|
| 257 | +struct nvdimm_bus *nvdimm_to_bus(struct nvdimm *nvdimm); |
---|
174 | 258 | struct nvdimm *to_nvdimm(struct device *dev); |
---|
175 | 259 | struct nd_region *to_nd_region(struct device *dev); |
---|
176 | 260 | struct device *nd_region_dev(struct nd_region *nd_region); |
---|
.. | .. |
---|
181 | 265 | struct kobject *nvdimm_kobj(struct nvdimm *nvdimm); |
---|
182 | 266 | unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm); |
---|
183 | 267 | void *nvdimm_provider_data(struct nvdimm *nvdimm); |
---|
184 | | -struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, |
---|
185 | | - const struct attribute_group **groups, unsigned long flags, |
---|
186 | | - unsigned long cmd_mask, int num_flush, |
---|
187 | | - struct resource *flush_wpq); |
---|
| 268 | +struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus, |
---|
| 269 | + void *provider_data, const struct attribute_group **groups, |
---|
| 270 | + unsigned long flags, unsigned long cmd_mask, int num_flush, |
---|
| 271 | + struct resource *flush_wpq, const char *dimm_id, |
---|
| 272 | + const struct nvdimm_security_ops *sec_ops, |
---|
| 273 | + const struct nvdimm_fw_ops *fw_ops); |
---|
| 274 | +static inline struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, |
---|
| 275 | + void *provider_data, const struct attribute_group **groups, |
---|
| 276 | + unsigned long flags, unsigned long cmd_mask, int num_flush, |
---|
| 277 | + struct resource *flush_wpq) |
---|
| 278 | +{ |
---|
| 279 | + return __nvdimm_create(nvdimm_bus, provider_data, groups, flags, |
---|
| 280 | + cmd_mask, num_flush, flush_wpq, NULL, NULL, NULL); |
---|
| 281 | +} |
---|
| 282 | + |
---|
188 | 283 | const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd); |
---|
189 | 284 | const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd); |
---|
190 | 285 | u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd, |
---|
.. | .. |
---|
211 | 306 | int generic_nvdimm_flush(struct nd_region *nd_region); |
---|
212 | 307 | int nvdimm_has_flush(struct nd_region *nd_region); |
---|
213 | 308 | int nvdimm_has_cache(struct nd_region *nd_region); |
---|
| 309 | +int nvdimm_in_overwrite(struct nvdimm *nvdimm); |
---|
| 310 | +bool is_nvdimm_sync(struct nd_region *nd_region); |
---|
| 311 | + |
---|
| 312 | +static inline int nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, void *buf, |
---|
| 313 | + unsigned int buf_len, int *cmd_rc) |
---|
| 314 | +{ |
---|
| 315 | + struct nvdimm_bus *nvdimm_bus = nvdimm_to_bus(nvdimm); |
---|
| 316 | + struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus); |
---|
| 317 | + |
---|
| 318 | + return nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len, cmd_rc); |
---|
| 319 | +} |
---|
214 | 320 | |
---|
215 | 321 | #ifdef CONFIG_ARCH_HAS_PMEM_API |
---|
216 | 322 | #define ARCH_MEMREMAP_PMEM MEMREMAP_WB |
---|