602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * CDDL HEADER START
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * The contents of this file are subject to the terms of the
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Common Development and Distribution License (the "License").
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * You may not use this file except in compliance with the License.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * See the License for the specific language governing permissions
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * and limitations under the License.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * When distributing Covered Code, include this CDDL HEADER in each
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * If applicable, add the following below this CDDL HEADER, with the
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * fields enclosed by brackets "[]" replaced with your own identifying
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * information: Portions Copyright [yyyy] [name of copyright owner]
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * CDDL HEADER END
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Functions in this file are shared between the disk and ses enumerators.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * A topo_list_t of all disks is returned by a successful disk_list_gather()
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * call, and the list is freed by a disk_list_free(). To create a 'disk' topo
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * node below a specific 'bay' parent node either disk_declare_path() or
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * disk_declare_addr() are called. The caller determines which 'disk' is
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * in which 'bay'. A disk's 'label' and 'authority' information come from
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * its parent 'bay' node.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/* common callback information for di_walk_node() and di_devlink_walk */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dcb_dnode; /* for di_devlink_walk only */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Given a /devices path for a whole disk, appending this extension gives the
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * path to a raw device that can be opened.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Methods for disks. This is used by the disk-transport module to
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * generate ereports based off SCSI disk status.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int disk_status(topo_mod_t *, tnode_t *, topo_version_t,
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim * Set the properties of the disk node, from dev_di_node_t data.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Properties include:
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * group: protocol properties: resource, asru, label, fru
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * group: authority properties: product-id, chasis-id, server-id
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * group: io properties: devfs-path, devid
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * group: storage properties:
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * - logical-disk, disk-model, disk-manufacturer, serial-number
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * - firmware-revision, capacity-in-bytes
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * NOTE: the io and storage groups won't be present if the dnode passed in is
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * NULL. This happens when a disk is found through ses, but is not enumerated
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * in the devinfo tree.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* pull the label property down from our parent 'bay' node */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* get the resource fmri, and use it as the fru */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* create/set the authority group */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((topo_pgroup_create(dtn, &disk_auth_pgroup, &err) != 0) &&
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* create the storage group */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (topo_pgroup_create(dtn, &storage_pgroup, &err) != 0) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson "create storage error %s\n", topo_strerror(err));
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* no dnode was found for this disk - skip the io and storage groups */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* form and set the asru */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if ((asru = topo_mod_devfmri(mod, FM_DEV_SCHEME_VERSION,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson dnode->ddn_dpath, dnode->ddn_devid)) == NULL) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (topo_node_asru_set(dtn, asru, 0, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* create/set the devfs-path and devid in the io group */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_prop_set_string(dtn, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (dnode->ddn_devid && topo_prop_set_string(dtn, TOPO_PGROUP_IO,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson TOPO_IO_DEVID, TOPO_PROP_IMMUTABLE, dnode->ddn_devid, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_prop_set_string_array(dtn, TOPO_PGROUP_IO, TOPO_IO_PHYS_PATH,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* set the storage group public /dev name */
f76de7499b0498d120c0c5ba970d061ccb587552Stephen Hanson topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* populate other misc storage group properties */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_mfg && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_model && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_serial && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_firm && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_cap && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
738c43b514a3570e657652233a5a19291a328a28Eric Schrock * Trim leading and trailing whitespace from the string.
738c43b514a3570e657652233a5a19291a328a28Eric Schrockstatic char *
738c43b514a3570e657652233a5a19291a328a28Eric Schrockdisk_trim_whitespace(topo_mod_t *mod, const char *begin)
940d71d237794874e18a0eb72f6564821a823517eschrock if ((buf = topo_mod_alloc(mod, count + 1)) == NULL)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock * Manufacturing strings can contain characters that are invalid for use in hc
738c43b514a3570e657652233a5a19291a328a28Eric Schrock * authority names. This trims leading and trailing whitespace, and
738c43b514a3570e657652233a5a19291a328a28Eric Schrock * substitutes any characters known to be bad.
738c43b514a3570e657652233a5a19291a328a28Eric Schrockdisk_auth_clean(topo_mod_t *mod, const char *str)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/* create the disk topo node */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dnode, const char *name, topo_instance_t i, tnode_t **rval)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson model = disk_auth_clean(mod, dnode->ddn_model);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson firm = disk_auth_clean(mod, dnode->ddn_firm);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson serial = disk_auth_clean(mod, dnode->ddn_serial);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* form 'part=' of fmri as "<mfg>-<model>" */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "hcfmri (%s%d/%s%d) error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dtn = topo_node_bind(mod, parent, name, i, fmri)) == NULL) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (topo_mod_errno(mod) == EMOD_NODE_BOUND) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * if disk 0 is already there then we're done
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "bind (%s%d/%s%d) error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* add the properties of the disk */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "disk_set_props (%s%d/%s%d) error %s\n",
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdisk_declare(topo_mod_t *mod, tnode_t *parent, dev_di_node_t *dnode,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson rval = disk_tnode_create(mod, parent, dnode, DISK, 0, &dtn);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "disk_tnode_create error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* register disk_methods against the disk topo node */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_method_register(mod, dtn, disk_methods) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "topo_method_register error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_declare_path(topo_mod_t *mod, tnode_t *parent, topo_list_t *listp,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth const char *path)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Check for match using physical phci (ddn_ppath). Use
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * di_devfs_path_match so generic.vs.non-generic names match.
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (disk_declare(mod, parent, dnode, NULL));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_declare_addr(topo_mod_t *mod, tnode_t *parent, topo_list_t *listp,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* Check for match using addr. */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * Used to declare a disk that has been discovered through other means (usually
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * ses), that is not enumerated in the devinfo tree.
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hansondisk_declare_non_enumerated(topo_mod_t *mod, tnode_t *parent, tnode_t **childp)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (disk_declare(mod, parent, NULL, childp));
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim/* di_devlink callback for dev_di_node_add */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* trim the slice off the public name */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* Establish the public /dev name (no slice) */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_lpath = topo_mod_strdup(mod, ctds ? ctds + 1 : devpath);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic void
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_di_node_free(topo_mod_t *mod, dev_di_node_t *dnode)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* free the stuff we point to */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* topo_mod_strfree does NULL checking. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strfree(mod, dnode->ddn_attached_port[i]);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* free self */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_di_node_add(di_node_t node, char *devid, disk_cbdata_t *cbp)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * Check for list duplicate using devid search.
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * Note if there is no devid, then we can end up with duplicates
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * in the list, but this doesn't do any harm.
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson dnode != NULL; dnode = topo_list_next(dnode)) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson devid_str_compare(dnode->ddn_devid, devid) == 0) {
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if ((dnode = topo_mod_zalloc(mod, sizeof (dev_di_node_t))) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* Establish the devid. */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson dnode->ddn_devid = topo_mod_strdup(mod, devid);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* Establish the devinfo dpath */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Establish the physical ppath and target ports. If the device is
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * non-mpxio then dpath and ppath are the same, and the target port is a
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * property of the device node.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * If dpath is a client node under scsi_vhci, then iterate over all
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * paths and get their physical paths and target port properrties.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * di_path_client_next_path call below will
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * return non-NULL, and ppath is set to the physical path to the first
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * pathinfo node.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * NOTE: It is possible to get a generic.vs.non-generic path
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * for di_devfs_path.vs.di_path_devfs_path like:
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * xml: /pci@7b,0/pci1022,7458@11/pci1000,3060@2/sd@2,0
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * pnode: /pci@7b,0/pci1022,7458@11/pci1000,3060@2/disk@2,0
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * To resolve this issue disk_declare_path() needs to use the
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * special di_devfs_path_match() interface.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth while ((pnode = di_path_client_next_path(node, pnode)) != NULL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (pathcount == 0) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_attached_port = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* There should be only one target port for a devinfo node. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* There should be one attached port if any. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* There should be one bridge port if any. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* processing a scsi_vhci device. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_attached_port = topo_mod_zalloc(mod,
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim * Find the public /dev name for a disk by adding a minor name and using
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * di_devlink interface for reverse translation (use devinfo path).
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type",
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim mlen = strlen(dnode->ddn_dpath) + strlen(extn) + 1;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if ((minorpath = topo_mod_alloc(mod, mlen)) == NULL)
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim "failed to determine logical path");
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim /* cache various bits of optional information about the device. */
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_mfg = disk_trim_whitespace(mod, s)) == NULL)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_model = disk_trim_whitespace(mod, s)) == NULL)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_firm = disk_trim_whitespace(mod, s)) == NULL)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_serial = disk_trim_whitespace(mod, s)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * To save kernel memory, the driver may not define
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * "device-dblksize" when its value is default DEV_BSIZE.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dnode->ddn_cap = topo_mod_strdup(mod, lentry)) == NULL)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson "adding %s\n", devid ? dnode->ddn_devid : "NULL devid");
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/* di_walk_node callback for disk_list_gather */
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson * If it's not a scsi_vhci client and doesn't have a target_port
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson * property and doesn't have a target property then it's not a storage
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson * device and we're not interested.
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (di_path_client_next_path(node, NULL) == NULL &&
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson (void) di_prop_lookup_strings(DDI_DEV_T_ANY, node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* create/find the devid scsi topology node */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_list_gather(topo_mod_t *mod, topo_list_t *listp)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((devtree = topo_mod_devinfo(mod)) == DI_NODE_NIL) {
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock "topo_mod_devinfo() failed");
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((devhdl = di_devlink_init(NULL, 0)) == DI_NODE_NIL) {
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock "di_devlink_init() failed");
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* walk the devinfo snapshot looking for disk nodes */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* order of delete/free is important */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Query the current disk status. If successful, the disk status is returned
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * as an nvlist consisting of at least the following members:
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * protocol string Supported protocol (currently "scsi")
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * status nvlist Arbitrary protocol-specific information
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * about the current state of the disk.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * faults nvlist A list of supported faults. Each
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * element of this list is a boolean value.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * An element's existence indicates that
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * the drive supports detecting this fault,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * and the value indicates the current
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * state of the fault.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * <fault-name> nvlist For each fault named in 'faults', a
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * nvlist describing protocol-specific
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * attributes of the fault.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * This method relies on the libdiskstatus library to query this information.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_status(topo_mod_t *mod, tnode_t *nodep, topo_version_t vers,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * If the caller specifies the "path" parameter, then this indicates
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * that we should use this instead of deriving it from the topo node
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (nvlist_lookup_string(in_nvl, "path", &fullpath) == 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Get the /devices path and attempt to open the disk status
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Note that sizeof(string) includes the terminating NULL byte
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth (void) snprintf(fullpath, pathlen, "/devices%s%s", devpath,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);