xref: /illumos-gate/usr/src/uts/common/io/scsi/impl/scsi_fm.c (revision 392e836b07e8da771953e4d64233b2abe4393efe)
19e1c849eSDavid Zhang - Sun Microsystems - Beijing China /*
29e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * CDDL HEADER START
39e1c849eSDavid Zhang - Sun Microsystems - Beijing China  *
49e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * The contents of this file are subject to the terms of the
59e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * Common Development and Distribution License (the "License").
69e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * You may not use this file except in compliance with the License.
79e1c849eSDavid Zhang - Sun Microsystems - Beijing China  *
89e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * or http://www.opensolaris.org/os/licensing.
109e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * See the License for the specific language governing permissions
119e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * and limitations under the License.
129e1c849eSDavid Zhang - Sun Microsystems - Beijing China  *
139e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * When distributing Covered Code, include this CDDL HEADER in each
149e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * If applicable, add the following below this CDDL HEADER, with the
169e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * fields enclosed by brackets "[]" replaced with your own identifying
179e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * information: Portions Copyright [yyyy] [name of copyright owner]
189e1c849eSDavid Zhang - Sun Microsystems - Beijing China  *
199e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * CDDL HEADER END
209e1c849eSDavid Zhang - Sun Microsystems - Beijing China  */
219e1c849eSDavid Zhang - Sun Microsystems - Beijing China /*
22*392e836bSGavin Maltby  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
239e1c849eSDavid Zhang - Sun Microsystems - Beijing China  */
249e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
259e1c849eSDavid Zhang - Sun Microsystems - Beijing China /*
269e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * SCSI FMA implementation
279e1c849eSDavid Zhang - Sun Microsystems - Beijing China  */
289e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
299e1c849eSDavid Zhang - Sun Microsystems - Beijing China #include <sys/scsi/scsi_types.h>
309e1c849eSDavid Zhang - Sun Microsystems - Beijing China #include <sys/sunmdi.h>
319e1c849eSDavid Zhang - Sun Microsystems - Beijing China #include <sys/va_list.h>
329e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
339e1c849eSDavid Zhang - Sun Microsystems - Beijing China #include <sys/ddi_impldefs.h>
349e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
359e1c849eSDavid Zhang - Sun Microsystems - Beijing China /* consolidation private interface to generate dev scheme ereport */
369e1c849eSDavid Zhang - Sun Microsystems - Beijing China extern void fm_dev_ereport_postv(dev_info_t *dip, dev_info_t *eqdip,
379e1c849eSDavid Zhang - Sun Microsystems - Beijing China     const char *devpath, const char *minor_name, const char *devid,
38*392e836bSGavin Maltby     const char *tpl0, const char *error_class, uint64_t ena, int sflag,
39*392e836bSGavin Maltby     nvlist_t *, va_list ap);
409e1c849eSDavid Zhang - Sun Microsystems - Beijing China extern char *mdi_pi_pathname_by_instance(int);
419e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
429e1c849eSDavid Zhang - Sun Microsystems - Beijing China #define	FM_SCSI_CLASS	"scsi"
439e1c849eSDavid Zhang - Sun Microsystems - Beijing China #define	ERPT_CLASS_SZ   sizeof (FM_SCSI_CLASS) + 1 + DDI_MAX_ERPT_CLASS + 1
449e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
459e1c849eSDavid Zhang - Sun Microsystems - Beijing China /*
469e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * scsi_fm_init: Initialize fma capabilities and register with IO
479e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * fault services.
489e1c849eSDavid Zhang - Sun Microsystems - Beijing China  */
499e1c849eSDavid Zhang - Sun Microsystems - Beijing China void
scsi_fm_init(struct scsi_device * sd)509e1c849eSDavid Zhang - Sun Microsystems - Beijing China scsi_fm_init(struct scsi_device *sd)
519e1c849eSDavid Zhang - Sun Microsystems - Beijing China {
529e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	dev_info_t	*dip = sd->sd_dev;
539e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
549e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	/*
559e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * fm-capable in driver.conf can be used to set fm_capabilities.
569e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * If fm-capable is not defined, then the last argument passed to
579e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * ddi_prop_get_int will be returned as the capabilities.
589e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 *
599e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * NOTE: by default scsi_fm_capable sets DDI_FM_EREPORT_CAPABLE.
609e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 */
619e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	sd->sd_fm_capable = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
629e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "fm-capable",
639e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	    scsi_fm_capable);
649e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
659e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	/*
669e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * Register capabilities with IO Fault Services. The capabilities
679e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * set above may not be supported by the parent nexus, in that
689e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * case some/all capability bits may be cleared.
699e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 *
709e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * NOTE: iblock cookies are not important because scsi HBAs
719e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * always interrupt below LOCK_LEVEL.
729e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 */
739e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	if (sd->sd_fm_capable != DDI_FM_NOT_CAPABLE)
749e1c849eSDavid Zhang - Sun Microsystems - Beijing China 		ddi_fm_init(dip, &sd->sd_fm_capable, NULL);
759e1c849eSDavid Zhang - Sun Microsystems - Beijing China }
769e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
779e1c849eSDavid Zhang - Sun Microsystems - Beijing China /*
789e1c849eSDavid Zhang - Sun Microsystems - Beijing China  * scsi_fm_fini: un-register with IO fault services.
799e1c849eSDavid Zhang - Sun Microsystems - Beijing China  */
809e1c849eSDavid Zhang - Sun Microsystems - Beijing China void
scsi_fm_fini(struct scsi_device * sd)819e1c849eSDavid Zhang - Sun Microsystems - Beijing China scsi_fm_fini(struct scsi_device *sd)
829e1c849eSDavid Zhang - Sun Microsystems - Beijing China {
839e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	dev_info_t	*dip = sd->sd_dev;
849e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
859e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	if (sd->sd_fm_capable != DDI_FM_NOT_CAPABLE)
869e1c849eSDavid Zhang - Sun Microsystems - Beijing China 		ddi_fm_fini(dip);
879e1c849eSDavid Zhang - Sun Microsystems - Beijing China }
889e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
899e1c849eSDavid Zhang - Sun Microsystems - Beijing China /*
909e1c849eSDavid Zhang - Sun Microsystems - Beijing China  *
91*392e836bSGavin Maltby  * scsi_fm_ereport_post - Post an ereport
929e1c849eSDavid Zhang - Sun Microsystems - Beijing China  */
939e1c849eSDavid Zhang - Sun Microsystems - Beijing China void
scsi_fm_ereport_post(struct scsi_device * sd,int path_instance,char * devpath,const char * error_class,uint64_t ena,char * devid,char * tpl0,int sflag,nvlist_t * pl,...)949e1c849eSDavid Zhang - Sun Microsystems - Beijing China scsi_fm_ereport_post(struct scsi_device *sd, int path_instance,
95*392e836bSGavin Maltby     char *devpath, const char *error_class, uint64_t ena,
96*392e836bSGavin Maltby     char *devid, char *tpl0, int sflag, nvlist_t *pl, ...)
979e1c849eSDavid Zhang - Sun Microsystems - Beijing China {
989e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	char		class[ERPT_CLASS_SZ];
999e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	dev_info_t	*dip = sd->sd_dev;
100*392e836bSGavin Maltby 	dev_info_t	*eqdip = dip;
101*392e836bSGavin Maltby 	char		*minor_name;
1029e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	va_list		ap;
1039e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
104*392e836bSGavin Maltby 	/*
105*392e836bSGavin Maltby 	 * If the scsi_device eqdip is not yet ereport capable, send the
106*392e836bSGavin Maltby 	 * report based on parent capabilities.  This is needed for
107*392e836bSGavin Maltby 	 * telemetry during enumeration.
108*392e836bSGavin Maltby 	 */
109*392e836bSGavin Maltby 	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(eqdip)))
110*392e836bSGavin Maltby 		eqdip = ddi_get_parent(eqdip);
111*392e836bSGavin Maltby 
1129e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	/* Add "scsi." as a prefix to the class */
1139e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	(void) snprintf(class, ERPT_CLASS_SZ, "%s.%s",
1149e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	    FM_SCSI_CLASS, error_class);
1159e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
1169e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	/*
117*392e836bSGavin Maltby 	 * Get the path:
118*392e836bSGavin Maltby 	 *
119*392e836bSGavin Maltby 	 * If path_instance is non-zero then the packet was
1209e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * sent to scsi_vhci. We return the pathinfo path_string associated
1219e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * with the path_instance path - which refers to the actual hardware.
122*392e836bSGavin Maltby 	 *
123*392e836bSGavin Maltby 	 * If path_instance is zero then use the devpath provided by the
124*392e836bSGavin Maltby 	 * caller;  if it was NULL then this will cause fm_dev_ereport_post
125*392e836bSGavin Maltby 	 * to use the devinfo path of the first devi we pass to it, ie
126*392e836bSGavin Maltby 	 * sd->sd_dev.
1279e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 */
1289e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	if (path_instance)
1299e1c849eSDavid Zhang - Sun Microsystems - Beijing China 		devpath = mdi_pi_pathname_by_instance(path_instance);
1309e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
1319e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	/*
1329e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * Set the minor_name to NULL. The block location of a media error
1339e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * is described by the 'lba' property. We use the 'lba' instead of
1349e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * the partition (minor_name) because the defect stays in the same
1359e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * place even when a repartition operation may result in the defect
1369e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * showing up in a different partition (minor_name). To support
1379e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * retire at the block/partition level, the user level retire agent
1389e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * should map the 'lba' to the current effected partition.
1399e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 */
1409e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	minor_name = NULL;
1419e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
1429e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	/*
1439e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * NOTE: If there is a 'linked' ena to be had, it should likely come
1449e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 * from the buf structure via the scsi_pkt pkt->pkt_bp.
1459e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	 */
1469e1c849eSDavid Zhang - Sun Microsystems - Beijing China 
1479e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	/* Post the ereport */
148*392e836bSGavin Maltby 	va_start(ap, pl);
149*392e836bSGavin Maltby 	fm_dev_ereport_postv(dip, eqdip, devpath, minor_name, devid, tpl0,
150*392e836bSGavin Maltby 	    class, ena, sflag, pl, ap);
1519e1c849eSDavid Zhang - Sun Microsystems - Beijing China 	va_end(ap);
1529e1c849eSDavid Zhang - Sun Microsystems - Beijing China }
153