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_dimm_flags {
19  	__u32 status;
20  	__u32 flags;
21  } __packed;
22  
23  struct nd_cmd_get_config_size {
24  	__u32 status;
25  	__u32 config_size;
26  	__u32 max_xfer;
27  } __packed;
28  
29  struct nd_cmd_get_config_data_hdr {
30  	__u32 in_offset;
31  	__u32 in_length;
32  	__u32 status;
33  	__u8 out_buf[];
34  } __packed;
35  
36  struct nd_cmd_set_config_hdr {
37  	__u32 in_offset;
38  	__u32 in_length;
39  	__u8 in_buf[];
40  } __packed;
41  
42  struct nd_cmd_vendor_hdr {
43  	__u32 opcode;
44  	__u32 in_length;
45  	__u8 in_buf[];
46  } __packed;
47  
48  struct nd_cmd_vendor_tail {
49  	__u32 status;
50  	__u32 out_length;
51  	__u8 out_buf[];
52  } __packed;
53  
54  struct nd_cmd_ars_cap {
55  	__u64 address;
56  	__u64 length;
57  	__u32 status;
58  	__u32 max_ars_out;
59  	__u32 clear_err_unit;
60  	__u16 flags;
61  	__u16 reserved;
62  } __packed;
63  
64  struct nd_cmd_ars_start {
65  	__u64 address;
66  	__u64 length;
67  	__u16 type;
68  	__u8 flags;
69  	__u8 reserved[5];
70  	__u32 status;
71  	__u32 scrub_time;
72  } __packed;
73  
74  struct nd_cmd_ars_status {
75  	__u32 status;
76  	__u32 out_length;
77  	__u64 address;
78  	__u64 length;
79  	__u64 restart_address;
80  	__u64 restart_length;
81  	__u16 type;
82  	__u16 flags;
83  	__u32 num_records;
84  	struct nd_ars_record {
85  		__u32 handle;
86  		__u32 reserved;
87  		__u64 err_address;
88  		__u64 length;
89  	} __packed records[];
90  } __packed;
91  
92  struct nd_cmd_clear_error {
93  	__u64 address;
94  	__u64 length;
95  	__u32 status;
96  	__u8 reserved[4];
97  	__u64 cleared;
98  } __packed;
99  
100  enum {
101  	ND_CMD_IMPLEMENTED = 0,
102  
103  	/* bus commands */
104  	ND_CMD_ARS_CAP = 1,
105  	ND_CMD_ARS_START = 2,
106  	ND_CMD_ARS_STATUS = 3,
107  	ND_CMD_CLEAR_ERROR = 4,
108  
109  	/* per-dimm commands */
110  	ND_CMD_SMART = 1,
111  	ND_CMD_SMART_THRESHOLD = 2,
112  	ND_CMD_DIMM_FLAGS = 3,
113  	ND_CMD_GET_CONFIG_SIZE = 4,
114  	ND_CMD_GET_CONFIG_DATA = 5,
115  	ND_CMD_SET_CONFIG_DATA = 6,
116  	ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
117  	ND_CMD_VENDOR_EFFECT_LOG = 8,
118  	ND_CMD_VENDOR = 9,
119  	ND_CMD_CALL = 10,
120  };
121  
122  enum {
123  	ND_ARS_VOLATILE = 1,
124  	ND_ARS_PERSISTENT = 2,
125  	ND_ARS_RETURN_PREV_DATA = 1 << 1,
126  	ND_CONFIG_LOCKED = 1,
127  };
128  
nvdimm_bus_cmd_name(unsigned cmd)129  static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
130  {
131  	switch (cmd) {
132  	case ND_CMD_ARS_CAP:		return "ars_cap";
133  	case ND_CMD_ARS_START:		return "ars_start";
134  	case ND_CMD_ARS_STATUS:		return "ars_status";
135  	case ND_CMD_CLEAR_ERROR:	return "clear_error";
136  	case ND_CMD_CALL:		return "cmd_call";
137  	default:			return "unknown";
138  	}
139  }
140  
nvdimm_cmd_name(unsigned cmd)141  static inline const char *nvdimm_cmd_name(unsigned cmd)
142  {
143  	switch (cmd) {
144  	case ND_CMD_SMART:			return "smart";
145  	case ND_CMD_SMART_THRESHOLD:		return "smart_thresh";
146  	case ND_CMD_DIMM_FLAGS:			return "flags";
147  	case ND_CMD_GET_CONFIG_SIZE:		return "get_size";
148  	case ND_CMD_GET_CONFIG_DATA:		return "get_data";
149  	case ND_CMD_SET_CONFIG_DATA:		return "set_data";
150  	case ND_CMD_VENDOR_EFFECT_LOG_SIZE:	return "effect_size";
151  	case ND_CMD_VENDOR_EFFECT_LOG:		return "effect_log";
152  	case ND_CMD_VENDOR:			return "vendor";
153  	case ND_CMD_CALL:			return "cmd_call";
154  	default:				return "unknown";
155  	}
156  }
157  
158  #define ND_IOCTL 'N'
159  
160  #define ND_IOCTL_DIMM_FLAGS		_IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
161  					struct nd_cmd_dimm_flags)
162  
163  #define ND_IOCTL_GET_CONFIG_SIZE	_IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_SIZE,\
164  					struct nd_cmd_get_config_size)
165  
166  #define ND_IOCTL_GET_CONFIG_DATA	_IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_DATA,\
167  					struct nd_cmd_get_config_data_hdr)
168  
169  #define ND_IOCTL_SET_CONFIG_DATA	_IOWR(ND_IOCTL, ND_CMD_SET_CONFIG_DATA,\
170  					struct nd_cmd_set_config_hdr)
171  
172  #define ND_IOCTL_VENDOR			_IOWR(ND_IOCTL, ND_CMD_VENDOR,\
173  					struct nd_cmd_vendor_hdr)
174  
175  #define ND_IOCTL_ARS_CAP		_IOWR(ND_IOCTL, ND_CMD_ARS_CAP,\
176  					struct nd_cmd_ars_cap)
177  
178  #define ND_IOCTL_ARS_START		_IOWR(ND_IOCTL, ND_CMD_ARS_START,\
179  					struct nd_cmd_ars_start)
180  
181  #define ND_IOCTL_ARS_STATUS		_IOWR(ND_IOCTL, ND_CMD_ARS_STATUS,\
182  					struct nd_cmd_ars_status)
183  
184  #define ND_IOCTL_CLEAR_ERROR		_IOWR(ND_IOCTL, ND_CMD_CLEAR_ERROR,\
185  					struct nd_cmd_clear_error)
186  
187  #define ND_DEVICE_DIMM 1            /* nd_dimm: container for "config data" */
188  #define ND_DEVICE_REGION_PMEM 2     /* nd_region: (parent of PMEM namespaces) */
189  #define ND_DEVICE_REGION_BLK 3      /* nd_region: (parent of BLK namespaces) */
190  #define ND_DEVICE_NAMESPACE_IO 4    /* legacy persistent memory */
191  #define ND_DEVICE_NAMESPACE_PMEM 5  /* PMEM namespace (may alias with BLK) */
192  #define ND_DEVICE_DAX_PMEM 7        /* Device DAX interface to pmem */
193  
194  enum nd_driver_flags {
195  	ND_DRIVER_DIMM            = 1 << ND_DEVICE_DIMM,
196  	ND_DRIVER_REGION_PMEM     = 1 << ND_DEVICE_REGION_PMEM,
197  	ND_DRIVER_REGION_BLK      = 1 << ND_DEVICE_REGION_BLK,
198  	ND_DRIVER_NAMESPACE_IO    = 1 << ND_DEVICE_NAMESPACE_IO,
199  	ND_DRIVER_NAMESPACE_PMEM  = 1 << ND_DEVICE_NAMESPACE_PMEM,
200  	ND_DRIVER_DAX_PMEM	  = 1 << ND_DEVICE_DAX_PMEM,
201  };
202  
203  enum ars_masks {
204  	ARS_STATUS_MASK = 0x0000FFFF,
205  	ARS_EXT_STATUS_SHIFT = 16,
206  };
207  
208  /*
209   * struct nd_cmd_pkg
210   *
211   * is a wrapper to a quasi pass thru interface for invoking firmware
212   * associated with nvdimms.
213   *
214   * INPUT PARAMETERS
215   *
216   * nd_family corresponds to the firmware (e.g. DSM) interface.
217   *
218   * nd_command are the function index advertised by the firmware.
219   *
220   * nd_size_in is the size of the input parameters being passed to firmware
221   *
222   * OUTPUT PARAMETERS
223   *
224   * nd_fw_size is the size of the data firmware wants to return for
225   * the call.  If nd_fw_size is greater than size of nd_size_out, only
226   * the first nd_size_out bytes are returned.
227   */
228  
229  struct nd_cmd_pkg {
230  	__u64   nd_family;		/* family of commands */
231  	__u64   nd_command;
232  	__u32   nd_size_in;		/* INPUT: size of input args */
233  	__u32   nd_size_out;		/* INPUT: size of payload */
234  	__u32   nd_reserved2[9];	/* reserved must be zero */
235  	__u32   nd_fw_size;		/* OUTPUT: size fw wants to return */
236  	unsigned char nd_payload[];	/* Contents of call      */
237  };
238  
239  /* These NVDIMM families represent pre-standardization command sets */
240  #define NVDIMM_FAMILY_INTEL 0
241  #define NVDIMM_FAMILY_HPE1 1
242  #define NVDIMM_FAMILY_HPE2 2
243  #define NVDIMM_FAMILY_MSFT 3
244  #define NVDIMM_FAMILY_HYPERV 4
245  #define NVDIMM_FAMILY_PAPR 5
246  #define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_PAPR
247  
248  #define NVDIMM_BUS_FAMILY_NFIT 0
249  #define NVDIMM_BUS_FAMILY_INTEL 1
250  #define NVDIMM_BUS_FAMILY_MAX NVDIMM_BUS_FAMILY_INTEL
251  
252  #define ND_IOCTL_CALL			_IOWR(ND_IOCTL, ND_CMD_CALL,\
253  					struct nd_cmd_pkg)
254  
255  #endif /* __NDCTL_H__ */
256