--- old/usr/src/cmd/fm/dicts/DISK.dict	Sat Apr 29 19:33:31 2017
+++ new/usr/src/cmd/fm/dicts/DISK.dict	Sat Apr 29 19:33:31 2017
@@ -1,6 +1,7 @@
 #
 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
+# Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
 #
 # CDDL HEADER START
 #
@@ -32,3 +33,4 @@
 fault.io.disk.self-test-failure=2
 fault.io.scsi.cmd.disk.dev.rqs.derr=3
 fault.io.scsi.cmd.disk.dev.rqs.merr=4
+fault.io.disk.ssm-wearout=8
--- old/usr/src/cmd/fm/dicts/DISK.po	Sat Apr 29 19:33:34 2017
+++ new/usr/src/cmd/fm/dicts/DISK.po	Sat Apr 29 19:33:34 2017
@@ -1,6 +1,7 @@
 #
 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
+# Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
 #
 # CDDL HEADER START
 #
@@ -104,3 +105,19 @@
 msgstr "It is likely that continued operation will result in data corruption, which may eventually cause the loss of service or the service degradation.\n"
 msgid "DISK-8000-4Q.action"
 msgstr "Schedule a repair procedure to replace the affected device. Use 'fmadm faulty' to find the affected disk.\n"
+#
+# code: DISK-8000-8D
+# keys: fault.io.disk.ssm-wearout
+#
+msgid "DISK-8000-8D.type"
+msgstr "Fault"
+msgid "DISK-8000-8D.severity"
+msgstr "Major"
+msgid "DISK-8000-8D.description"
+msgstr "A solid state media device is nearing end of life as projected by the manufacturer."
+msgid "DISK-8000-8D.response"
+msgstr "None."
+msgid "DISK-8000-8D.impact"
+msgstr "Performance degradation is likely and continued operation of this device will cause drive failure and potential data loss."
+msgid "DISK-8000-8D.action"
+msgstr "Schedule a repair procedure to replace the affected drive.\nUse fmdump -V -u <EVENT_ID> to identify the drive."
--- old/usr/src/cmd/fm/eversholt/files/common/disk.esc	Sat Apr 29 19:33:38 2017
+++ new/usr/src/cmd/fm/eversholt/files/common/disk.esc	Sat Apr 29 19:33:38 2017
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #pragma dictionary "DISK"
@@ -44,7 +45,8 @@
  * to trigger a fault when recovery/relocation is not possible.
  *
  * We let the engine propagate one error only once every 1 minute and then if we
- * still get 2 or more * errors within 24 hours for the same LBA, there is a fault.
+ * still get 2 or more errors within 24 hours for the same LBA,
+ * there is a fault.
  */
 engine serd.io.scsi.cmd.disk.dev.rqs.merr@P, N=1, T=24h;
 
@@ -185,6 +187,7 @@
     FITrate=10, FRU=P, ASRU=P;
 event fault.io.disk.self-test-failure@P, FITrate=10,
     FITrate=10, FRU=P, ASRU=P;
+event fault.io.disk.ssm-wearout@P;
 
 /*
  * ereports.
@@ -192,6 +195,7 @@
 event ereport.io.scsi.disk.over-temperature@P;
 event ereport.io.scsi.disk.predictive-failure@P;
 event ereport.io.scsi.disk.self-test-failure@P;
+event ereport.io.scsi.disk.ssm-wearout@P;
 
 /*
  * Propagations.
@@ -206,3 +210,10 @@
     ereport.io.scsi.disk.predictive-failure@P {
     setpayloadprop("asc", payloadprop("additional-sense-code")) &&
     setpayloadprop("ascq", payloadprop("additional-sense-code-qualifier")) };
+
+prop fault.io.disk.ssm-wearout@P ->
+    ereport.io.scsi.disk.ssm-wearout@P {
+    setpayloadprop("current-wearout-percentage",
+    payloadprop("current-ssm-wearout"))
+    && setpayloadprop("threshold-wearout-percentage",
+    payloadprop("threshold-ssm-wearout")) };
--- old/usr/src/cmd/fm/modules/common/disk-monitor/disk_monitor.c	Sat Apr 29 19:33:42 2017
+++ new/usr/src/cmd/fm/modules/common/disk-monitor/disk_monitor.c	Sat Apr 29 19:33:42 2017
@@ -22,6 +22,7 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -158,6 +159,10 @@
 	    DISK_ERROR_CLASS "." FM_FAULT_DISK_TESTFAIL))
 		action_prop = DISK_PROP_STFAILACTION;
 
+	if (fmd_nvl_class_match(hdl, nvl,
+	    DISK_ERROR_CLASS "." FM_FAULT_SSM_WEAROUT))
+		action_prop = DISK_PROP_SSMWEAROUTACTION;
+
 	dm_fault_indicator_set(diskp, INDICATOR_ON);
 
 	if (action_prop != NULL &&
--- old/usr/src/cmd/fm/modules/common/disk-monitor/diskmon_conf.h	Sat Apr 29 19:33:46 2017
+++ new/usr/src/cmd/fm/modules/common/disk-monitor/diskmon_conf.h	Sat Apr 29 19:33:46 2017
@@ -22,13 +22,12 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef _DISKMOND_CONF_H
 #define	_DISKMOND_CONF_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Configuration File data
  */
@@ -62,6 +61,7 @@
 #define	DISK_PROP_FRUACTION		"fru-update-action"
 #define	DISK_PROP_OTEMPACTION		"overtemp-action"
 #define	DISK_PROP_STFAILACTION		"selftest-fail-action"
+#define	DISK_PROP_SSMWEAROUTACTION	"ssm-wearout-action"
 
 /* Properties for the "ap" subentity */
 #define	DISK_AP_PROP_APID "path"
--- old/usr/src/cmd/fm/modules/common/disk-transport/disk-transport.conf	Sat Apr 29 19:33:49 2017
+++ new/usr/src/cmd/fm/modules/common/disk-transport/disk-transport.conf	Sat Apr 29 19:33:50 2017
@@ -21,5 +21,8 @@
 #
 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
+# Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+#
+# To disable transport of "high solid state media used %" faults uncomment:
+# setprop ignore-ssm-wearout true
--- old/usr/src/cmd/fm/modules/common/disk-transport/disk_transport.c	Sat Apr 29 19:33:53 2017
+++ new/usr/src/cmd/fm/modules/common/disk-transport/disk_transport.c	Sat Apr 29 19:33:53 2017
@@ -21,10 +21,9 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Disk error transport module
  *
@@ -32,17 +31,18 @@
  * and FMA ereports.  It is a read-only transport module, and checks for the
  * following failures:
  *
- * 	- overtemp
- * 	- predictive failure
- * 	- self-test failure
+ *	- overtemp
+ *	- predictive failure
+ *	- self-test failure
+ *	- solid state media wearout
  *
  * These failures are detected via the TOPO_METH_DISK_STATUS method, which
  * leverages libdiskstatus to do the actual analysis.  This transport module is
  * in charge of the following tasks:
  *
- * 	- discovering available devices
- * 	- periodically checking devices
- * 	- managing device addition/removal
+ *	- discovering available devices
+ *	- periodically checking devices
+ *	- managing device addition/removal
  */
 
 #include <ctype.h>
@@ -113,7 +113,6 @@
 	char *protocol;
 	int err;
 	disk_monitor_t *dmp = arg;
-	uint64_t ena;
 	nvpair_t *elem;
 	boolean_t fault;
 	nvlist_t *details;
@@ -152,10 +151,8 @@
 
 	nvlist_free(in);
 
-	ena = fmd_event_ena_create(dmp->dm_hdl);
-
 	/*
-	 * Add any faults.
+	 * Check for faults and post ereport(s) if needed
 	 */
 	if (nvlist_lookup_nvlist(result, "faults", &faults) == 0 &&
 	    nvlist_lookup_string(result, "protocol", &protocol) == 0) {
@@ -170,8 +167,15 @@
 			    &details) != 0)
 				continue;
 
+			if (strcmp(nvpair_name(elem),
+			    FM_EREPORT_SCSI_SSMWEAROUT) == 0 &&
+			    fmd_prop_get_int32(dmp->dm_hdl,
+			    "ignore-ssm-wearout") == FMD_B_TRUE)
+				continue;
+
 			dt_post_ereport(dmp->dm_hdl, dmp->dm_xprt, protocol,
-			    nvpair_name(elem), ena, fmri, details);
+			    nvpair_name(elem),
+			    fmd_event_ena_create(dmp->dm_hdl), fmri, details);
 		}
 	}
 
@@ -248,6 +252,7 @@
 	{ "interval", FMD_TYPE_TIME, "1h" },
 	{ "min-interval", FMD_TYPE_TIME, "1min" },
 	{ "simulate", FMD_TYPE_STRING, "" },
+	{ "ignore-ssm-wearout", FMD_TYPE_BOOL, "false"},
 	{ NULL, 0, NULL }
 };
 
@@ -262,7 +267,7 @@
 };
 
 static const fmd_hdl_info_t fmd_info = {
-	"Disk Transport Agent", "1.0", &fmd_ops, fmd_props
+	"Disk Transport Agent", "1.1", &fmd_ops, fmd_props
 };
 
 void
@@ -289,7 +294,7 @@
 	 * the developer to substitute a faulty device based off all or part of
 	 * an FMRI string.  For example, one could do:
 	 *
-	 * 	setprop simulate "bay=4/disk=4	/path/to/sim.so"
+	 *	setprop simulate "bay=4/disk=4	/path/to/sim.so"
 	 *
 	 * When the transport module encounters an FMRI containing the given
 	 * string, then it will open the simulator file instead of the
--- old/usr/src/cmd/fm/modules/common/zfs-retire/zfs-retire.conf	Sat Apr 29 19:33:57 2017
+++ new/usr/src/cmd/fm/modules/common/zfs-retire/zfs-retire.conf	Sat Apr 29 19:33:57 2017
@@ -25,6 +25,9 @@
 #
 # fmd configuration file for the zfs retire agent.
 #
+# To enable automated retire for SSM wearout faults uncomment the line below:
+# setprop ssm_wearout_skip_retire false
+#
 subscribe fault.fs.zfs.*
 subscribe fault.io.*
 subscribe resource.fs.zfs.removed
--- old/usr/src/cmd/fm/modules/common/zfs-retire/zfs_retire.c	Sat Apr 29 19:34:00 2017
+++ new/usr/src/cmd/fm/modules/common/zfs-retire/zfs_retire.c	Sat Apr 29 19:34:00 2017
@@ -427,6 +427,14 @@
 		    &retire) == 0 && retire == 0)
 			continue;
 
+		if (fmd_nvl_class_match(hdl, fault,
+		    "fault.io.disk.ssm-wearout") &&
+		    fmd_prop_get_int32(hdl, "ssm_wearout_skip_retire") ==
+		    FMD_B_TRUE) {
+			fmd_hdl_debug(hdl, "zfs-retire: ignoring SSM fault");
+			continue;
+		}
+
 		/*
 		 * While we subscribe to fault.fs.zfs.*, we only take action
 		 * for faults targeting a specific vdev (open failure or SERD
@@ -561,6 +569,7 @@
 
 static const fmd_prop_t fmd_props[] = {
 	{ "spare_on_remove", FMD_TYPE_BOOL, "true" },
+	{ "ssm_wearout_skip_retire", FMD_TYPE_BOOL, "true"},
 	{ NULL, 0, NULL }
 };
 
--- old/usr/src/lib/fm/libdiskstatus/common/ds_impl.h	Sat Apr 29 19:34:03 2017
+++ new/usr/src/lib/fm/libdiskstatus/common/ds_impl.h	Sat Apr 29 19:34:03 2017
@@ -21,13 +21,12 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_DS_IMPL_H
 #define	_DS_IMPL_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <dlfcn.h>
 #include <libnvpair.h>
 #include <sys/types.h>
@@ -53,6 +52,7 @@
 	nvlist_t		*ds_overtemp;	/* overtemp */
 	nvlist_t		*ds_predfail;	/* predict fail */
 	nvlist_t		*ds_testfail;	/* self test fail */
+	nvlist_t		*ds_ssmwearout;	/* SSM wearout fail */
 	int			ds_error;	/* last error */
 	nvlist_t		*ds_state;	/* protocol state */
 };
@@ -60,6 +60,7 @@
 #define	DS_FAULT_OVERTEMP	0x1
 #define	DS_FAULT_PREDFAIL	0x2
 #define	DS_FAULT_TESTFAIL	0x4
+#define	DS_FAULT_SSMWEAROUT	0x8
 
 extern void dprintf(const char *, ...);
 extern void ddump(const char *, const void *, size_t);
--- old/usr/src/lib/fm/libdiskstatus/common/ds_scsi.c	Sat Apr 29 19:34:06 2017
+++ new/usr/src/lib/fm/libdiskstatus/common/ds_scsi.c	Sat Apr 29 19:34:06 2017
@@ -21,10 +21,9 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <assert.h>
 #include <errno.h>
 #include <libdiskstatus.h>
@@ -77,6 +76,8 @@
     scsi_log_parameter_header_t *, int, nvlist_t *);
 static int logpage_selftest_verify(ds_scsi_info_t *,
     scsi_log_parameter_header_t *, int, nvlist_t *);
+static int logpage_ssm_verify(ds_scsi_info_t *,
+    scsi_log_parameter_header_t *, int, nvlist_t *);
 
 static int logpage_ie_analyze(ds_scsi_info_t *,
     scsi_log_parameter_header_t *, int);
@@ -84,6 +85,8 @@
     scsi_log_parameter_header_t *, int);
 static int logpage_selftest_analyze(ds_scsi_info_t *,
     scsi_log_parameter_header_t *, int);
+static int logpage_ssm_analyze(ds_scsi_info_t *,
+    scsi_log_parameter_header_t *, int);
 
 static struct logpage_validation_entry log_validation[] = {
 	{ LOGPAGE_IE,		LOGPAGE_SUPP_IE,
@@ -94,7 +97,10 @@
 	    logpage_temp_verify, logpage_temp_analyze },
 	{ LOGPAGE_SELFTEST,	LOGPAGE_SUPP_SELFTEST,
 	    "self-test",
-	    logpage_selftest_verify, logpage_selftest_analyze }
+	    logpage_selftest_verify, logpage_selftest_analyze },
+	{ LOGPAGE_SSM,		LOGPAGE_SUPP_SSM,
+	    FM_EREPORT_SCSI_SSMWEAROUT,
+	    logpage_ssm_verify, logpage_ssm_analyze }
 };
 
 #define	NLOG_VALIDATION	(sizeof (log_validation) / sizeof (log_validation[0]))
@@ -757,6 +763,51 @@
 }
 
 /*
+ * Verify the contents of the Solid State Media (SSM) log page.
+ * As of SBC3r36 SSM log page contains one log parameter:
+ * "Percentage Used Endurance Indicator" which is mandatory.
+ * For the verification phase, we sanity check this parameter
+ * by making sure it's present and it's length is set to 0x04.
+ */
+static int
+logpage_ssm_verify(ds_scsi_info_t *sip,
+    scsi_log_parameter_header_t *lphp, int log_length, nvlist_t *nvl)
+{
+	ushort_t param_code;
+	int i, plen = 0;
+
+	for (i = 0; i < log_length; i += plen) {
+		lphp = (scsi_log_parameter_header_t *)((char *)lphp + plen);
+		param_code = BE_16(lphp->lph_param);
+
+		switch (param_code) {
+		case LOGPARAM_PRCNT_USED:
+			if (nvlist_add_boolean_value(nvl,
+			    FM_EREPORT_SCSI_SSMWEAROUT, B_TRUE) != 0)
+				return (scsi_set_errno(sip, EDS_NOMEM));
+			if (lphp->lph_length != LOGPARAM_PRCNT_USED_PARAM_LEN) {
+				if (nvlist_add_uint8(nvl,
+				    "invalid-length", lphp->lph_length) != 0)
+					return (scsi_set_errno(sip, EDS_NOMEM));
+
+				dprintf("solid state media logpage bad len\n");
+				break;
+			}
+
+			/* verification succeded */
+			return (0);
+		}
+
+		plen = lphp->lph_length +
+		    sizeof (scsi_log_parameter_header_t);
+	}
+
+	/* verification failed */
+	sip->si_supp_log &= ~LOGPAGE_SUPP_SSM;
+	return (0);
+}
+
+/*
  * Load the current IE mode pages
  */
 static int
@@ -1144,6 +1195,65 @@
 	return (0);
 }
 
+/*
+ * Analyze the contents of the Solid State Media (SSM) log page's
+ * "Percentage Used Endurance Indicator" log parameter.
+ * We generate a fault if the percentage used is equal to or over
+ * PRCNT_USED_FAULT_THRSH
+ */
+static int
+logpage_ssm_analyze(ds_scsi_info_t *sip, scsi_log_parameter_header_t *lphp,
+    int log_length)
+{
+	uint16_t param_code;
+	scsi_ssm_log_param_t *ssm;
+	nvlist_t *nvl;
+	int i, plen = 0;
+
+	assert(sip->si_dsp->ds_overtemp == NULL);
+	if (nvlist_alloc(&sip->si_dsp->ds_overtemp, NV_UNIQUE_NAME, 0) != 0)
+		return (scsi_set_errno(sip, EDS_NOMEM));
+	nvl = sip->si_dsp->ds_overtemp;
+
+	for (i = 0; i < log_length; i += plen) {
+		lphp = (scsi_log_parameter_header_t *)((uint8_t *)lphp + plen);
+		param_code = BE_16(lphp->lph_param);
+		ssm = (scsi_ssm_log_param_t *)lphp;
+
+		switch (param_code) {
+		case LOGPARAM_PRCNT_USED:
+			if (lphp->lph_length != LOGPARAM_PRCNT_USED_PARAM_LEN)
+				break;
+
+			if ((nvlist_add_uint8(nvl,
+			    FM_EREPORT_PAYLOAD_SCSI_CURSSMWEAROUT,
+			    ssm->ssm_prcnt_used) != 0) ||
+			    (nvlist_add_uint8(nvl,
+			    FM_EREPORT_PAYLOAD_SCSI_THRSHSSMWEAROUT,
+			    PRCNT_USED_FAULT_THRSH) != 0))
+				return (scsi_set_errno(sip, EDS_NOMEM));
+
+			if (ssm->ssm_prcnt_used >= PRCNT_USED_FAULT_THRSH)
+				sip->si_dsp->ds_faults |= DS_FAULT_SSMWEAROUT;
+
+			return (0);
+		}
+
+		plen = lphp->lph_length +
+		    sizeof (scsi_log_parameter_header_t);
+	}
+
+	/*
+	 * If we got this far we didn't see LOGPARAM_PRCNT_USED
+	 * which is strange since we verified that it's there
+	 */
+	dprintf("solid state media logpage analyze failed\n");
+#if DEBUG
+	abort();
+#endif
+	return (scsi_set_errno(sip, EDS_NOT_SUPPORTED));
+}
+
 /*
  * Analyze the IE mode sense page explicitly.  This is only needed if the IE log
  * page is not supported.
--- old/usr/src/lib/fm/libdiskstatus/common/ds_scsi.h	Sat Apr 29 19:34:09 2017
+++ new/usr/src/lib/fm/libdiskstatus/common/ds_scsi.h	Sat Apr 29 19:34:09 2017
@@ -21,13 +21,12 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_DS_SCSI_H
 #define	_DS_SCSI_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/byteorder.h>
 #include <sys/scsi/scsi.h>
@@ -50,12 +49,14 @@
 typedef struct scsi_log_header {
 #if defined(_BIT_FIELDS_LTOH)
 	uint8_t		lh_code : 6,
-			__reserved : 2;
+			lh_spf : 1,
+			lh_ds : 1;
 #else
-	uint8_t		__reserved : 2,
+	uint8_t		lh_ds : 1,
+			lh_spf : 1,
 			lh_code : 6;
 #endif
-	uint8_t		__reserved2;
+	uint8_t		lh_subpage;
 	uint16_t	lh_length;
 } scsi_log_header_t;
 
@@ -158,6 +159,20 @@
 	    sizeof (scsi_log_parameter_header_t))
 
 /*
+ * Described in SBC3
+ */
+typedef struct scsi_ssm_log_param {
+	scsi_log_parameter_header_t ssm_hdr;
+	uint16_t		__reserved2;
+	uint8_t			__reserved1;
+	uchar_t			ssm_prcnt_used;
+} scsi_ssm_log_param_t;
+
+#define	LOGPARAM_PRCNT_USED		0x0001
+#define	LOGPARAM_PRCNT_USED_PARAM_LEN	0x04
+#define	PRCNT_USED_FAULT_THRSH		90
+
+/*
  * Mode sense/select page header information
  */
 typedef struct scsi_ms_header {
@@ -278,6 +293,8 @@
 #define	LOGPAGE_TEMP		0x0d
 #define	LOGPAGE_SELFTEST	0x10
 #define	LOGPAGE_IE		0x2f
+/* Solid State Media log page code */
+#define	LOGPAGE_SSM		0x11
 
 /* ASC constants */
 #define	ASC_INVALID_OPCODE				0x20
@@ -307,6 +324,7 @@
 #define	LOGPAGE_SUPP_IE			0x1
 #define	LOGPAGE_SUPP_TEMP		0x2
 #define	LOGPAGE_SUPP_SELFTEST		0x4
+#define	LOGPAGE_SUPP_SSM		0x8
 
 #define	MSG_BUFLEN	256
 
--- old/usr/src/lib/fm/libdiskstatus/common/libdiskstatus.c	Sat Apr 29 19:34:12 2017
+++ new/usr/src/lib/fm/libdiskstatus/common/libdiskstatus.c	Sat Apr 29 19:34:12 2017
@@ -21,10 +21,9 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Disk status library
  *
@@ -33,9 +32,10 @@
  * SCSI (and therefore SATA) disks are currently supported.  The library is
  * capable of detecting the following status conditions:
  *
- * 	- Predictive failure
- * 	- Overtemp
- * 	- Self-test failure
+ *	- Predictive failure
+ *	- Overtemp
+ *	- Self-test failure
+ *	- Solid State Media wearout
  */
 
 #include <assert.h>
@@ -131,6 +131,7 @@
 	nvlist_free(dsp->ds_predfail);
 	nvlist_free(dsp->ds_overtemp);
 	nvlist_free(dsp->ds_testfail);
+	nvlist_free(dsp->ds_ssmwearout);
 	if (dsp->ds_data)
 		dsp->ds_transport->dt_close(dsp->ds_data);
 	(void) close(dsp->ds_fd);
@@ -172,6 +173,8 @@
 	nvlist_free(dsp->ds_testfail);
 	nvlist_free(dsp->ds_predfail);
 	nvlist_free(dsp->ds_overtemp);
+	nvlist_free(dsp->ds_ssmwearout);
+	dsp->ds_ssmwearout = NULL;
 	dsp->ds_testfail = dsp->ds_overtemp = dsp->ds_predfail = NULL;
 	dsp->ds_faults = 0;
 
@@ -222,6 +225,15 @@
 		    dsp->ds_overtemp)) != 0)
 			goto nverror;
 	}
+
+	if (dsp->ds_ssmwearout != NULL) {
+		if ((err = nvlist_add_boolean_value(faults,
+		    FM_EREPORT_SCSI_SSMWEAROUT,
+		    (dsp->ds_faults & DS_FAULT_SSMWEAROUT) != 0)) != 0 ||
+		    (err = nvlist_add_nvlist(nvl, FM_EREPORT_SCSI_SSMWEAROUT,
+		    dsp->ds_ssmwearout)) != 0)
+			goto nverror;
+	}
 
 	if ((err = nvlist_add_nvlist(nvl, "faults", faults)) != 0)
 		goto nverror;
--- old/usr/src/uts/common/sys/fm/io/disk.h	Sat Apr 29 19:34:15 2017
+++ new/usr/src/uts/common/sys/fm/io/disk.h	Sat Apr 29 19:34:15 2017
@@ -21,13 +21,12 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_SYS_FM_IO_DISK_H
 #define	_SYS_FM_IO_DISK_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -37,6 +36,7 @@
 #define	FM_FAULT_DISK_PREDFAIL		"predictive-failure"
 #define	FM_FAULT_DISK_OVERTEMP		"over-temperature"
 #define	FM_FAULT_DISK_TESTFAIL		"self-test-failure"
+#define	FM_FAULT_SSM_WEAROUT		"ssm-wearout"
 
 #ifdef	__cplusplus
 }
--- old/usr/src/uts/common/sys/fm/io/scsi.h	Sat Apr 29 19:34:19 2017
+++ new/usr/src/uts/common/sys/fm/io/scsi.h	Sat Apr 29 19:34:19 2017
@@ -21,13 +21,12 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_SYS_FM_IO_SCSI_H
 #define	_SYS_FM_IO_SCSI_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -48,6 +47,10 @@
 #define	FM_EREPORT_PAYLOAD_SCSI_CURTEMP		"current-temperature"
 #define	FM_EREPORT_PAYLOAD_SCSI_THRESHTEMP	"threshold-temperature"
 
+#define	FM_EREPORT_SCSI_SSMWEAROUT		"ssm-wearout"
+#define	FM_EREPORT_PAYLOAD_SCSI_CURSSMWEAROUT	"current-ssm-wearout"
+#define	FM_EREPORT_PAYLOAD_SCSI_THRSHSSMWEAROUT	"threshold-ssm-wearout"
+
 #define	FM_EREPORT_SCSI_TESTFAIL		"self-test-failure"
 #define	FM_EREPORT_PAYLOAD_SCSI_RESULTCODE	"result-code"
 #define	FM_EREPORT_PAYLOAD_SCSI_ADDRESS		"address"
