Home | History | Annotate | Download | only in linux
      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 	__u16 flags;
    109 	__u16 reserved;
    110 } __packed;
    111 
    112 struct nd_cmd_ars_start {
    113 	__u64 address;
    114 	__u64 length;
    115 	__u16 type;
    116 	__u8 flags;
    117 	__u8 reserved[5];
    118 	__u32 status;
    119 	__u32 scrub_time;
    120 } __packed;
    121 
    122 struct nd_cmd_ars_status {
    123 	__u32 status;
    124 	__u32 out_length;
    125 	__u64 address;
    126 	__u64 length;
    127 	__u64 restart_address;
    128 	__u64 restart_length;
    129 	__u16 type;
    130 	__u16 flags;
    131 	__u32 num_records;
    132 	struct nd_ars_record {
    133 		__u32 handle;
    134 		__u32 reserved;
    135 		__u64 err_address;
    136 		__u64 length;
    137 	} __packed records[0];
    138 } __packed;
    139 
    140 struct nd_cmd_clear_error {
    141 	__u64 address;
    142 	__u64 length;
    143 	__u32 status;
    144 	__u8 reserved[4];
    145 	__u64 cleared;
    146 } __packed;
    147 
    148 enum {
    149 	ND_CMD_IMPLEMENTED = 0,
    150 
    151 	/* bus commands */
    152 	ND_CMD_ARS_CAP = 1,
    153 	ND_CMD_ARS_START = 2,
    154 	ND_CMD_ARS_STATUS = 3,
    155 	ND_CMD_CLEAR_ERROR = 4,
    156 
    157 	/* per-dimm commands */
    158 	ND_CMD_SMART = 1,
    159 	ND_CMD_SMART_THRESHOLD = 2,
    160 	ND_CMD_DIMM_FLAGS = 3,
    161 	ND_CMD_GET_CONFIG_SIZE = 4,
    162 	ND_CMD_GET_CONFIG_DATA = 5,
    163 	ND_CMD_SET_CONFIG_DATA = 6,
    164 	ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
    165 	ND_CMD_VENDOR_EFFECT_LOG = 8,
    166 	ND_CMD_VENDOR = 9,
    167 	ND_CMD_CALL = 10,
    168 };
    169 
    170 enum {
    171 	ND_ARS_VOLATILE = 1,
    172 	ND_ARS_PERSISTENT = 2,
    173 	ND_ARS_RETURN_PREV_DATA = 1 << 1,
    174 	ND_CONFIG_LOCKED = 1,
    175 };
    176 
    177 static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
    178 {
    179 	static const char * const names[] = {
    180 		[ND_CMD_ARS_CAP] = "ars_cap",
    181 		[ND_CMD_ARS_START] = "ars_start",
    182 		[ND_CMD_ARS_STATUS] = "ars_status",
    183 		[ND_CMD_CLEAR_ERROR] = "clear_error",
    184 		[ND_CMD_CALL] = "cmd_call",
    185 	};
    186 
    187 	if (cmd < ARRAY_SIZE(names) && names[cmd])
    188 		return names[cmd];
    189 	return "unknown";
    190 }
    191 
    192 static inline const char *nvdimm_cmd_name(unsigned cmd)
    193 {
    194 	static const char * const names[] = {
    195 		[ND_CMD_SMART] = "smart",
    196 		[ND_CMD_SMART_THRESHOLD] = "smart_thresh",
    197 		[ND_CMD_DIMM_FLAGS] = "flags",
    198 		[ND_CMD_GET_CONFIG_SIZE] = "get_size",
    199 		[ND_CMD_GET_CONFIG_DATA] = "get_data",
    200 		[ND_CMD_SET_CONFIG_DATA] = "set_data",
    201 		[ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size",
    202 		[ND_CMD_VENDOR_EFFECT_LOG] = "effect_log",
    203 		[ND_CMD_VENDOR] = "vendor",
    204 		[ND_CMD_CALL] = "cmd_call",
    205 	};
    206 
    207 	if (cmd < ARRAY_SIZE(names) && names[cmd])
    208 		return names[cmd];
    209 	return "unknown";
    210 }
    211 
    212 #define ND_IOCTL 'N'
    213 
    214 #define ND_IOCTL_SMART			_IOWR(ND_IOCTL, ND_CMD_SMART,\
    215 					struct nd_cmd_smart)
    216 
    217 #define ND_IOCTL_SMART_THRESHOLD	_IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
    218 					struct nd_cmd_smart_threshold)
    219 
    220 #define ND_IOCTL_DIMM_FLAGS		_IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
    221 					struct nd_cmd_dimm_flags)
    222 
    223 #define ND_IOCTL_GET_CONFIG_SIZE	_IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_SIZE,\
    224 					struct nd_cmd_get_config_size)
    225 
    226 #define ND_IOCTL_GET_CONFIG_DATA	_IOWR(ND_IOCTL, ND_CMD_GET_CONFIG_DATA,\
    227 					struct nd_cmd_get_config_data_hdr)
    228 
    229 #define ND_IOCTL_SET_CONFIG_DATA	_IOWR(ND_IOCTL, ND_CMD_SET_CONFIG_DATA,\
    230 					struct nd_cmd_set_config_hdr)
    231 
    232 #define ND_IOCTL_VENDOR			_IOWR(ND_IOCTL, ND_CMD_VENDOR,\
    233 					struct nd_cmd_vendor_hdr)
    234 
    235 #define ND_IOCTL_ARS_CAP		_IOWR(ND_IOCTL, ND_CMD_ARS_CAP,\
    236 					struct nd_cmd_ars_cap)
    237 
    238 #define ND_IOCTL_ARS_START		_IOWR(ND_IOCTL, ND_CMD_ARS_START,\
    239 					struct nd_cmd_ars_start)
    240 
    241 #define ND_IOCTL_ARS_STATUS		_IOWR(ND_IOCTL, ND_CMD_ARS_STATUS,\
    242 					struct nd_cmd_ars_status)
    243 
    244 #define ND_IOCTL_CLEAR_ERROR		_IOWR(ND_IOCTL, ND_CMD_CLEAR_ERROR,\
    245 					struct nd_cmd_clear_error)
    246 
    247 #define ND_DEVICE_DIMM 1            /* nd_dimm: container for "config data" */
    248 #define ND_DEVICE_REGION_PMEM 2     /* nd_region: (parent of PMEM namespaces) */
    249 #define ND_DEVICE_REGION_BLK 3      /* nd_region: (parent of BLK namespaces) */
    250 #define ND_DEVICE_NAMESPACE_IO 4    /* legacy persistent memory */
    251 #define ND_DEVICE_NAMESPACE_PMEM 5  /* PMEM namespace (may alias with BLK) */
    252 #define ND_DEVICE_NAMESPACE_BLK 6   /* BLK namespace (may alias with PMEM) */
    253 #define ND_DEVICE_DAX_PMEM 7        /* Device DAX interface to pmem */
    254 
    255 enum nd_driver_flags {
    256 	ND_DRIVER_DIMM            = 1 << ND_DEVICE_DIMM,
    257 	ND_DRIVER_REGION_PMEM     = 1 << ND_DEVICE_REGION_PMEM,
    258 	ND_DRIVER_REGION_BLK      = 1 << ND_DEVICE_REGION_BLK,
    259 	ND_DRIVER_NAMESPACE_IO    = 1 << ND_DEVICE_NAMESPACE_IO,
    260 	ND_DRIVER_NAMESPACE_PMEM  = 1 << ND_DEVICE_NAMESPACE_PMEM,
    261 	ND_DRIVER_NAMESPACE_BLK   = 1 << ND_DEVICE_NAMESPACE_BLK,
    262 	ND_DRIVER_DAX_PMEM	  = 1 << ND_DEVICE_DAX_PMEM,
    263 };
    264 
    265 enum {
    266 	ND_MIN_NAMESPACE_SIZE = 0x00400000,
    267 };
    268 
    269 enum ars_masks {
    270 	ARS_STATUS_MASK = 0x0000FFFF,
    271 	ARS_EXT_STATUS_SHIFT = 16,
    272 };
    273 
    274 /*
    275  * struct nd_cmd_pkg
    276  *
    277  * is a wrapper to a quasi pass thru interface for invoking firmware
    278  * associated with nvdimms.
    279  *
    280  * INPUT PARAMETERS
    281  *
    282  * nd_family corresponds to the firmware (e.g. DSM) interface.
    283  *
    284  * nd_command are the function index advertised by the firmware.
    285  *
    286  * nd_size_in is the size of the input parameters being passed to firmware
    287  *
    288  * OUTPUT PARAMETERS
    289  *
    290  * nd_fw_size is the size of the data firmware wants to return for
    291  * the call.  If nd_fw_size is greater than size of nd_size_out, only
    292  * the first nd_size_out bytes are returned.
    293  */
    294 
    295 struct nd_cmd_pkg {
    296 	__u64   nd_family;		/* family of commands */
    297 	__u64   nd_command;
    298 	__u32   nd_size_in;		/* INPUT: size of input args */
    299 	__u32   nd_size_out;		/* INPUT: size of payload */
    300 	__u32   nd_reserved2[9];	/* reserved must be zero */
    301 	__u32   nd_fw_size;		/* OUTPUT: size fw wants to return */
    302 	unsigned char nd_payload[];	/* Contents of call      */
    303 };
    304 
    305 /* These NVDIMM families represent pre-standardization command sets */
    306 #define NVDIMM_FAMILY_INTEL 0
    307 #define NVDIMM_FAMILY_HPE1 1
    308 #define NVDIMM_FAMILY_HPE2 2
    309 #define NVDIMM_FAMILY_MSFT 3
    310 
    311 #define ND_IOCTL_CALL			_IOWR(ND_IOCTL, ND_CMD_CALL,\
    312 					struct nd_cmd_pkg)
    313 
    314 #endif /* __NDCTL_H__ */
    315