• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (c) 2014-2016, Intel Corporation.
3   *
4   * This program is free software; you can redistribute it and/or modify it
5   * under the terms and conditions of the GNU Lesser General Public License,
6   * version 2.1, as published by the Free Software Foundation.
7   *
8   * This program is distributed in the hope it will be useful, but WITHOUT ANY
9   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10   * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
11   * more details.
12   */
13  #ifndef __NDCTL_H__
14  #define __NDCTL_H__
15  
16  #include <linux/types.h>
17  
18  struct nd_cmd_smart {
19  	__u32 status;
20  	__u8 data[128];
21  } __packed;
22  
23  #define ND_SMART_HEALTH_VALID	(1 << 0)
24  #define ND_SMART_SPARES_VALID	(1 << 1)
25  #define ND_SMART_USED_VALID	(1 << 2)
26  #define ND_SMART_TEMP_VALID 	(1 << 3)
27  #define ND_SMART_CTEMP_VALID 	(1 << 4)
28  #define ND_SMART_ALARM_VALID	(1 << 9)
29  #define ND_SMART_SHUTDOWN_VALID	(1 << 10)
30  #define ND_SMART_VENDOR_VALID	(1 << 11)
31  #define ND_SMART_SPARE_TRIP	(1 << 0)
32  #define ND_SMART_TEMP_TRIP	(1 << 1)
33  #define ND_SMART_CTEMP_TRIP	(1 << 2)
34  #define ND_SMART_NON_CRITICAL_HEALTH	(1 << 0)
35  #define ND_SMART_CRITICAL_HEALTH	(1 << 1)
36  #define ND_SMART_FATAL_HEALTH		(1 << 2)
37  
38  struct nd_smart_payload {
39  	__u32 flags;
40  	__u8 reserved0[4];
41  	__u8 health;
42  	__u8 spares;
43  	__u8 life_used;
44  	__u8 alarm_flags;
45  	__u16 temperature;
46  	__u16 ctrl_temperature;
47  	__u8 reserved1[15];
48  	__u8 shutdown_state;
49  	__u32 vendor_size;
50  	__u8 vendor_data[92];
51  } __packed;
52  
53  struct nd_cmd_smart_threshold {
54  	__u32 status;
55  	__u8 data[8];
56  } __packed;
57  
58  struct nd_smart_threshold_payload {
59  	__u8 alarm_control;
60  	__u8 reserved0;
61  	__u16 temperature;
62  	__u8 spares;
63  	__u8 reserved[3];
64  } __packed;
65  
66  struct nd_cmd_dimm_flags {
67  	__u32 status;
68  	__u32 flags;
69  } __packed;
70  
71  struct nd_cmd_get_config_size {
72  	__u32 status;
73  	__u32 config_size;
74  	__u32 max_xfer;
75  } __packed;
76  
77  struct nd_cmd_get_config_data_hdr {
78  	__u32 in_offset;
79  	__u32 in_length;
80  	__u32 status;
81  	__u8 out_buf[0];
82  } __packed;
83  
84  struct nd_cmd_set_config_hdr {
85  	__u32 in_offset;
86  	__u32 in_length;
87  	__u8 in_buf[0];
88  } __packed;
89  
90  struct nd_cmd_vendor_hdr {
91  	__u32 opcode;
92  	__u32 in_length;
93  	__u8 in_buf[0];
94  } __packed;
95  
96  struct nd_cmd_vendor_tail {
97  	__u32 status;
98  	__u32 out_length;
99  	__u8 out_buf[0];
100  } __packed;
101  
102  struct nd_cmd_ars_cap {
103  	__u64 address;
104  	__u64 length;
105  	__u32 status;
106  	__u32 max_ars_out;
107  	__u32 clear_err_unit;
108  	__u32 reserved;
109  } __packed;
110  
111  struct nd_cmd_ars_start {
112  	__u64 address;
113  	__u64 length;
114  	__u16 type;
115  	__u8 flags;
116  	__u8 reserved[5];
117  	__u32 status;
118  	__u32 scrub_time;
119  } __packed;
120  
121  struct nd_cmd_ars_status {
122  	__u32 status;
123  	__u32 out_length;
124  	__u64 address;
125  	__u64 length;
126  	__u64 restart_address;
127  	__u64 restart_length;
128  	__u16 type;
129  	__u16 flags;
130  	__u32 num_records;
131  	struct nd_ars_record {
132  		__u32 handle;
133  		__u32 reserved;
134  		__u64 err_address;
135  		__u64 length;
136  	} __packed records[0];
137  } __packed;
138  
139  struct nd_cmd_clear_error {
140  	__u64 address;
141  	__u64 length;
142  	__u32 status;
143  	__u8 reserved[4];
144  	__u64 cleared;
145  } __packed;
146  
147  enum {
148  	ND_CMD_IMPLEMENTED = 0,
149  
150  	/* bus commands */
151  	ND_CMD_ARS_CAP = 1,
152  	ND_CMD_ARS_START = 2,
153  	ND_CMD_ARS_STATUS = 3,
154  	ND_CMD_CLEAR_ERROR = 4,
155  
156  	/* per-dimm commands */
157  	ND_CMD_SMART = 1,
158  	ND_CMD_SMART_THRESHOLD = 2,
159  	ND_CMD_DIMM_FLAGS = 3,
160  	ND_CMD_GET_CONFIG_SIZE = 4,
161  	ND_CMD_GET_CONFIG_DATA = 5,
162  	ND_CMD_SET_CONFIG_DATA = 6,
163  	ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
164  	ND_CMD_VENDOR_EFFECT_LOG = 8,
165  	ND_CMD_VENDOR = 9,
166  	ND_CMD_CALL = 10,
167  };
168  
169  enum {
170  	ND_ARS_VOLATILE = 1,
171  	ND_ARS_PERSISTENT = 2,
172  };
173  
nvdimm_bus_cmd_name(unsigned cmd)174  static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
175  {
176  	static const char * const names[] = {
177  		[ND_CMD_ARS_CAP] = "ars_cap",
178  		[ND_CMD_ARS_START] = "ars_start",
179  		[ND_CMD_ARS_STATUS] = "ars_status",
180  		[ND_CMD_CLEAR_ERROR] = "clear_error",
181  	};
182  
183  	if (cmd < ARRAY_SIZE(names) && names[cmd])
184  		return names[cmd];
185  	return "unknown";
186  }
187  
nvdimm_cmd_name(unsigned cmd)188  static inline const char *nvdimm_cmd_name(unsigned cmd)
189  {
190  	static const char * const names[] = {
191  		[ND_CMD_SMART] = "smart",
192  		[ND_CMD_SMART_THRESHOLD] = "smart_thresh",
193  		[ND_CMD_DIMM_FLAGS] = "flags",
194  		[ND_CMD_GET_CONFIG_SIZE] = "get_size",
195  		[ND_CMD_GET_CONFIG_DATA] = "get_data",
196  		[ND_CMD_SET_CONFIG_DATA] = "set_data",
197  		[ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size",
198  		[ND_CMD_VENDOR_EFFECT_LOG] = "effect_log",
199  		[ND_CMD_VENDOR] = "vendor",
200  		[ND_CMD_CALL] = "cmd_call",
201  	};
202  
203  	if (cmd < ARRAY_SIZE(names) && names[cmd])
204  		return names[cmd];
205  	return "unknown";
206  }
207  
208  #define ND_IOCTL 'N'
209  
210  #define ND_IOCTL_SMART			_IOWR(ND_IOCTL, ND_CMD_SMART,\
211  					struct nd_cmd_smart)
212  
213  #define ND_IOCTL_SMART_THRESHOLD	_IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
214  					struct nd_cmd_smart_threshold)
215  
216  #define ND_IOCTL_DIMM_FLAGS		_IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
217  					struct nd_cmd_dimm_flags)
218  
219  #define ND_IOCTL_GET_CONFIG_SIZE	_IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_SIZE,\
220  					struct nd_cmd_get_config_size)
221  
222  #define ND_IOCTL_GET_CONFIG_DATA	_IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_DATA,\
223  					struct nd_cmd_get_config_data_hdr)
224  
225  #define ND_IOCTL_SET_CONFIG_DATA	_IOWR(ND_IOCTL, ND_CMD_SET_CONFIG_DATA,\
226  					struct nd_cmd_set_config_hdr)
227  
228  #define ND_IOCTL_VENDOR			_IOWR(ND_IOCTL, ND_CMD_VENDOR,\
229  					struct nd_cmd_vendor_hdr)
230  
231  #define ND_IOCTL_ARS_CAP		_IOWR(ND_IOCTL, ND_CMD_ARS_CAP,\
232  					struct nd_cmd_ars_cap)
233  
234  #define ND_IOCTL_ARS_START		_IOWR(ND_IOCTL, ND_CMD_ARS_START,\
235  					struct nd_cmd_ars_start)
236  
237  #define ND_IOCTL_ARS_STATUS		_IOWR(ND_IOCTL, ND_CMD_ARS_STATUS,\
238  					struct nd_cmd_ars_status)
239  
240  #define ND_IOCTL_CLEAR_ERROR		_IOWR(ND_IOCTL, ND_CMD_CLEAR_ERROR,\
241  					struct nd_cmd_clear_error)
242  
243  #define ND_DEVICE_DIMM 1            /* nd_dimm: container for "config data" */
244  #define ND_DEVICE_REGION_PMEM 2     /* nd_region: (parent of PMEM namespaces) */
245  #define ND_DEVICE_REGION_BLK 3      /* nd_region: (parent of BLK namespaces) */
246  #define ND_DEVICE_NAMESPACE_IO 4    /* legacy persistent memory */
247  #define ND_DEVICE_NAMESPACE_PMEM 5  /* PMEM namespace (may alias with BLK) */
248  #define ND_DEVICE_NAMESPACE_BLK 6   /* BLK namespace (may alias with PMEM) */
249  #define ND_DEVICE_DAX_PMEM 7        /* Device DAX interface to pmem */
250  
251  enum nd_driver_flags {
252  	ND_DRIVER_DIMM            = 1 << ND_DEVICE_DIMM,
253  	ND_DRIVER_REGION_PMEM     = 1 << ND_DEVICE_REGION_PMEM,
254  	ND_DRIVER_REGION_BLK      = 1 << ND_DEVICE_REGION_BLK,
255  	ND_DRIVER_NAMESPACE_IO    = 1 << ND_DEVICE_NAMESPACE_IO,
256  	ND_DRIVER_NAMESPACE_PMEM  = 1 << ND_DEVICE_NAMESPACE_PMEM,
257  	ND_DRIVER_NAMESPACE_BLK   = 1 << ND_DEVICE_NAMESPACE_BLK,
258  	ND_DRIVER_DAX_PMEM	  = 1 << ND_DEVICE_DAX_PMEM,
259  };
260  
261  enum {
262  	ND_MIN_NAMESPACE_SIZE = 0x00400000,
263  };
264  
265  enum ars_masks {
266  	ARS_STATUS_MASK = 0x0000FFFF,
267  	ARS_EXT_STATUS_SHIFT = 16,
268  };
269  
270  /*
271   * struct nd_cmd_pkg
272   *
273   * is a wrapper to a quasi pass thru interface for invoking firmware
274   * associated with nvdimms.
275   *
276   * INPUT PARAMETERS
277   *
278   * nd_family corresponds to the firmware (e.g. DSM) interface.
279   *
280   * nd_command are the function index advertised by the firmware.
281   *
282   * nd_size_in is the size of the input parameters being passed to firmware
283   *
284   * OUTPUT PARAMETERS
285   *
286   * nd_fw_size is the size of the data firmware wants to return for
287   * the call.  If nd_fw_size is greater than size of nd_size_out, only
288   * the first nd_size_out bytes are returned.
289   */
290  
291  struct nd_cmd_pkg {
292  	__u64   nd_family;		/* family of commands */
293  	__u64   nd_command;
294  	__u32   nd_size_in;		/* INPUT: size of input args */
295  	__u32   nd_size_out;		/* INPUT: size of payload */
296  	__u32   nd_reserved2[9];	/* reserved must be zero */
297  	__u32   nd_fw_size;		/* OUTPUT: size fw wants to return */
298  	unsigned char nd_payload[];	/* Contents of call      */
299  };
300  
301  /* These NVDIMM families represent pre-standardization command sets */
302  #define NVDIMM_FAMILY_INTEL 0
303  #define NVDIMM_FAMILY_HPE1 1
304  #define NVDIMM_FAMILY_HPE2 2
305  #define NVDIMM_FAMILY_MSFT 3
306  
307  #define ND_IOCTL_CALL			_IOWR(ND_IOCTL, ND_CMD_CALL,\
308  					struct nd_cmd_pkg)
309  
310  #endif /* __NDCTL_H__ */
311