ddifm.c revision eae2e508a8e70b1ec407b10bd068c080651bbe5c
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas#pragma ident "%Z%%M% %I% %E% SMI"
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Fault Management for Device Drivers
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Device drivers wishing to participate in fault management may do so by
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * first initializing their fault management state and capabilties via
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * ddi_fm_init(). If the system supports the requested FM capabilities,
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * the IO framework will intialize FM state and return a bit mask of the
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * requested capabilities.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * If the system does not support the requested FM capabilities,
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * the device driver must behave in accordance with the programming semantics
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * defined below for the capabilities returned from ddi_fm_init().
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * ddi_fm_init() must be called at attach(9E) time and ddi_fm_fini() must be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * called from detach(9E) to perform FM clean-up.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Driver Fault Management Capabilities
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * DDI_FM_NOT_CAPABLE
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * This is the default fault management capability for drivers. Drivers
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * that implement no fault management capabilites or do not participate
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * in fault management activities have their FM capability bitmask set
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * DDI_FM_EREPORT_CAPABLE
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * When this capability bit is set, drivers are expected to generate error
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * report events via ddi_ereport_post() for the associated faults
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * that are diagnosed by the IO fault manager DE. ddi_ereport_post()
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * may be called in any context subject to the constraints specified
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * by the interrupt iblock cookie returned during initialization.
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright * Error reports resulting from hardware component specific and common IO
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * fault and driver defects must be accompanied by an Eversholt fault
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * tree (.eft) by the Solaris fault manager (fmd(1M)) for
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * diagnosis.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * DDI_FM_ERRCB_CAPABLE
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Device drivers are expected to implement and register an error
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * handler callback function. ddi_fm_handler_register() and
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * ddi_fm_handler_unregister() must be
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * called in passive kernel context, typically during an attach(9E)
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * or detach(9E) operation. When called by the FM IO framework,
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * the callback function should check for error conditions for the
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * hardware and software under its control. All detected errors
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * should have ereport events generated for them.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Upon completion of the error handler callback, the driver should
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * return one of the following values:
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * #define DDI_FM_OK - no error was detected
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * #define DDI_FM_FATAL - a fatal error was detected
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * #define DDI_FM_NONFATAL - a non-fatal error was detected
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * #define DDI_FM_UNKNOWN - the error status is unknown
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * To insure single threaded access to error handling callbacks,
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * the device driver may use i_ddi_fm_handler_enter() and
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * i_ddi_fm_handler_exit() when entering and exiting the callback.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Device drivers are expected to set-up access and DMA handles
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * with FM-specific attributes designed to allow nexus parent
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * drivers to flag any errors seen during subsequent IO transactions.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Drivers must set the devacc_attr_acc_flag member of their
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * ddi_device_acc_attr_t structures to DDI_FLAGERR_ACC or DDI_CAUTIOUS_ACC.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * For DMA transactions, driver must set the dma_attr_flags of
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * their ddi_dma_attr_t structures to DDI_DMA_FLAGERR.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Upon completion of an IO transaction, device drivers are expected
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * to check the status of host-side hardware access and device-side
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * dma completions by calling ddi_acc_err_check() or ddi_dma_err_check()
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * respectively. If the handle is associated with an error detected by
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * the nexus parent or FM IO framework, ddi_fm_error_t data (status, ena
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * and error expectation) is returned. If status of DDI_FM_NONFATAL or
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * DDI_FM_FATAL is returned, the ena is valid and the expectation flag
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * will be set to 1 if the error was unexpected (i.e. not the result
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * of a peek or poke type operation).
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * ddi_acc_err_check() and ddi_dma_err_check() may be called in any
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * context subject to the constraints specified by the interrupt
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * iblock cookie returned during initialization.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Device drivers should generate an access (DDI_FM_IO_ACC) or dma
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * (DDI_FM_IO_DMA) data path error report if DDI_FM_NONFATAL or
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * DDI_FM_FATAL is returned.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/kobj.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/fm/util.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <sys/fm/io/ddi.h>
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego#define ERPT_CLASS_SZ sizeof (DDI_IO_CLASS) + sizeof (FM_EREPORT_CLASS) + \
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego/* Globals */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States {"fm_cache_grew", KSTAT_DATA_UINT64 },
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States {"acc_err", KSTAT_DATA_UINT64 },
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States/*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Update the service state following the detection of an
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * error.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoddi_fm_service_impact(dev_info_t *dip, int svc_impact)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States case DDI_SERVICE_DEGRADED:
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States DEVI_SET_DEVICE_DEGRADED(dip);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (DEVI_IS_DEVICE_DEGRADED(dip)) {
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrighterpt_post_sleep(dev_info_t *dip, const char *error_class, uint64_t ena,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States char device_path[MAXPATHLEN];
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright * Driver defect - should not call with DDI_SLEEP while
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright * in interrupt context
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego i_ddi_drv_ereport_post(dip, DVR_ECONTEXT, NULL, DDI_NOSLEEP);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if ((ereport = fm_nvlist_create(NULL)) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use the dev_path/devid for this device instance.
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright DDI_PROP_DONTPASS, DEVID_PROP_NAME, &devid) == DDI_SUCCESS) {
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL,
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL,
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego (void) snprintf(ddi_error_class, ERPT_CLASS_SZ, "%s.%s",
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego fm_ereport_set(ereport, version, ddi_error_class,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrighterpt_post_nosleep(dev_info_t *dip, struct i_ddi_fmhdl *fmhdl,
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright const char *error_class, uint64_t ena, uint8_t version, va_list ap)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego ereport = errorq_elem_nvl(fmhdl->fh_errorq, eqep);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use the dev_path/devid for this device instance.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States device_path[0] = '/';
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States device_path[1] = '\0';
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States } else {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (void) ddi_pathname(dip, device_path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States device_path, NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States DDI_IO_CLASS, error_class);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States name = va_arg(ap, char *);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (0);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesi_ddi_drv_ereport_post(dev_info_t *dip, const char *error_class,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States nvlist_t *errp, int sflag)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int i;
for (i = 0; i < depth; ++i) {
if (errp)
NULL);
if (errp)
NULL);
int sflag, ...)
int ret;
char *name;
ap);
if (ret != 0)
void *impl_data)
if (servicing_interrupt()) {
if (servicing_interrupt()) {
sizeof (struct i_ddi_fmkstat));
return (DDI_FM_NOT_CAPABLE);
int flag)
int flag)