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