602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/*
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * CDDL HEADER START
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *
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 *
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * or http://www.opensolaris.org/os/licensing.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * See the License for the specific language governing permissions
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * and limitations under the License.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *
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 *
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * CDDL HEADER END
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/*
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/*
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Functions in this file are shared between the disk and ses enumerators.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *
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 */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
940d71d237794874e18a0eb72f6564821a823517eschrock#include <ctype.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <strings.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <libdevinfo.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <devid.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <sys/libdevid.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <pthread.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <inttypes.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <sys/dkio.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <sys/scsi/scsi_types.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <fm/topo_mod.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <fm/topo_list.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <fm/libdiskstatus.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include <sys/fm/protocol.h>
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim#include <sys/scsi/generic/inquiry.h>
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#include "disk.h"
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/* common callback information for di_walk_node() and di_devlink_walk */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthtypedef struct disk_cbdata {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_t *dcb_mod;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_list_t *dcb_list;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth di_devlink_handle_t dcb_devhdl;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dcb_dnode; /* for di_devlink_walk only */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth} disk_cbdata_t;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/*
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 */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#if defined(__i386) || defined(__amd64)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#define PHYS_EXTN ":q,raw"
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#elif defined(__sparc) || defined(__sparcv9)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#define PHYS_EXTN ":c,raw"
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#else
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#error Unknown architecture
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth#endif
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/*
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Methods for disks. This is used by the disk-transport module to
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * generate ereports based off SCSI disk status.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int disk_status(topo_mod_t *, tnode_t *, topo_version_t,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_t *, nvlist_t **);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic const topo_method_t disk_methods[] = {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth { TOPO_METH_DISK_STATUS, TOPO_METH_DISK_STATUS_DESC,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_METH_DISK_STATUS_VERSION, TOPO_STABILITY_INTERNAL,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth disk_status },
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth { NULL }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth};
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic const topo_pgroup_info_t io_pgroup = {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_PGROUP_IO,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STABILITY_PRIVATE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STABILITY_PRIVATE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth 1
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth};
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic const topo_pgroup_info_t disk_auth_pgroup = {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth FM_FMRI_AUTHORITY,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STABILITY_PRIVATE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STABILITY_PRIVATE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth 1
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth};
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic const topo_pgroup_info_t storage_pgroup = {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STABILITY_PRIVATE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STABILITY_PRIVATE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth 1
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth};
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/*
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 *
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 */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_set_props(topo_mod_t *mod, tnode_t *parent,
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim tnode_t *dtn, dev_di_node_t *dnode)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_t *asru = NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *label = NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_t *fmri = NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int err;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* pull the label property down from our parent 'bay' node */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_node_label(parent, &label, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "label error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_node_label_set(dtn, label, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "label_set error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* get the resource fmri, and use it as the fru */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_node_resource(dtn, &fmri, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "resource error: %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_node_fru_set(dtn, fmri, 0, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "fru_set error: %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* create/set the authority group */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((topo_pgroup_create(dtn, &disk_auth_pgroup, &err) != 0) &&
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth (err != ETOPO_PROP_DEFD)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "create disk_auth error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* create the storage group */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (topo_pgroup_create(dtn, &storage_pgroup, &err) != 0) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson topo_mod_dprintf(mod, "disk_set_props: "
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson "create storage error %s\n", topo_strerror(err));
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson goto error;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* no dnode was found for this disk - skip the io and storage groups */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (dnode == NULL) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson err = 0;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson goto out;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson
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 err = ETOPO_FMRI_UNKNOWN;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson topo_mod_dprintf(mod, "disk_set_props: "
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson "asru error %s\n", topo_strerror(err));
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson goto error;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (topo_node_asru_set(dtn, asru, 0, &err) != 0) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson topo_mod_dprintf(mod, "disk_set_props: "
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson "asru_set error %s\n", topo_strerror(err));
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson goto error;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* create/set the devfs-path and devid in the io group */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_pgroup_create(dtn, &io_pgroup, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "create io error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_prop_set_string(dtn, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_PROP_IMMUTABLE, dnode->ddn_dpath, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set dev error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
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_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set devid error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_ppath_count != 0 &&
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_prop_set_string_array(dtn, TOPO_PGROUP_IO, TOPO_IO_PHYS_PATH,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_PROP_IMMUTABLE, (const char **)dnode->ddn_ppath,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_ppath_count, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set phys-path error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* set the storage group public /dev name */
f76de7499b0498d120c0c5ba970d061ccb587552Stephen Hanson if (dnode->ddn_lpath != NULL &&
f76de7499b0498d120c0c5ba970d061ccb587552Stephen Hanson topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STORAGE_LOGICAL_DISK_NAME, TOPO_PROP_IMMUTABLE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_lpath, &err) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set disk_name error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* populate other misc storage group properties */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_mfg && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STORAGE_MANUFACTURER, TOPO_PROP_IMMUTABLE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_mfg, &err) != 0)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set mfg error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_model && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STORAGE_MODEL, TOPO_PROP_IMMUTABLE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_model, &err) != 0)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set model error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_serial && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STORAGE_SERIAL_NUM, TOPO_PROP_IMMUTABLE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_serial, &err) != 0)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set serial error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_firm && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STORAGE_FIRMWARE_REV, TOPO_PROP_IMMUTABLE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_firm, &err) != 0)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set firm error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_cap && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_STORAGE_CAPACITY, TOPO_PROP_IMMUTABLE,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_cap, &err) != 0)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_set_props: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "set cap error %s\n", topo_strerror(err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth err = 0;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipekout:
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(fmri);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (label)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, label);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(asru);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (err);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dctherror: err = topo_mod_seterrno(mod, err);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto out;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
940d71d237794874e18a0eb72f6564821a823517eschrock/*
738c43b514a3570e657652233a5a19291a328a28Eric Schrock * Trim leading and trailing whitespace from the string.
940d71d237794874e18a0eb72f6564821a823517eschrock */
738c43b514a3570e657652233a5a19291a328a28Eric Schrockstatic char *
738c43b514a3570e657652233a5a19291a328a28Eric Schrockdisk_trim_whitespace(topo_mod_t *mod, const char *begin)
940d71d237794874e18a0eb72f6564821a823517eschrock{
940d71d237794874e18a0eb72f6564821a823517eschrock const char *end;
738c43b514a3570e657652233a5a19291a328a28Eric Schrock char *buf;
940d71d237794874e18a0eb72f6564821a823517eschrock size_t count;
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock if (begin == NULL)
940d71d237794874e18a0eb72f6564821a823517eschrock return (NULL);
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock end = begin + strlen(begin);
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock while (begin < end && isspace(*begin))
940d71d237794874e18a0eb72f6564821a823517eschrock begin++;
940d71d237794874e18a0eb72f6564821a823517eschrock while (begin < end && isspace(*(end - 1)))
940d71d237794874e18a0eb72f6564821a823517eschrock end--;
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock count = end - begin;
940d71d237794874e18a0eb72f6564821a823517eschrock if ((buf = topo_mod_alloc(mod, count + 1)) == NULL)
940d71d237794874e18a0eb72f6564821a823517eschrock return (NULL);
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock (void) strlcpy(buf, begin, count + 1);
940d71d237794874e18a0eb72f6564821a823517eschrock
738c43b514a3570e657652233a5a19291a328a28Eric Schrock return (buf);
738c43b514a3570e657652233a5a19291a328a28Eric Schrock}
738c43b514a3570e657652233a5a19291a328a28Eric Schrock
738c43b514a3570e657652233a5a19291a328a28Eric Schrock/*
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 Schrock */
738c43b514a3570e657652233a5a19291a328a28Eric Schrockchar *
738c43b514a3570e657652233a5a19291a328a28Eric Schrockdisk_auth_clean(topo_mod_t *mod, const char *str)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock{
738c43b514a3570e657652233a5a19291a328a28Eric Schrock char *buf, *p;
738c43b514a3570e657652233a5a19291a328a28Eric Schrock
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if (str == NULL)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock return (NULL);
738c43b514a3570e657652233a5a19291a328a28Eric Schrock
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((buf = topo_mod_strdup(mod, str)) == NULL)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock return (NULL);
738c43b514a3570e657652233a5a19291a328a28Eric Schrock
738c43b514a3570e657652233a5a19291a328a28Eric Schrock while ((p = strpbrk(buf, " :=")) != NULL)
738c43b514a3570e657652233a5a19291a328a28Eric Schrock *p = '-';
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock return (buf);
940d71d237794874e18a0eb72f6564821a823517eschrock}
940d71d237794874e18a0eb72f6564821a823517eschrock
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/* create the disk topo node */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hansonstatic int
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_tnode_create(topo_mod_t *mod, tnode_t *parent,
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dnode, const char *name, topo_instance_t i, tnode_t **rval)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int len;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_t *fmri;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth tnode_t *dtn;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *part = NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_t *auth;
940d71d237794874e18a0eb72f6564821a823517eschrock char *mfg, *model, *firm, *serial;
940d71d237794874e18a0eb72f6564821a823517eschrock
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson *rval = NULL;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (dnode != NULL) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson mfg = disk_auth_clean(mod, dnode->ddn_mfg);
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);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson } else {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson mfg = model = firm = serial = NULL;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* form 'part=' of fmri as "<mfg>-<model>" */
940d71d237794874e18a0eb72f6564821a823517eschrock if (mfg != NULL && model != NULL) {
940d71d237794874e18a0eb72f6564821a823517eschrock len = strlen(mfg) + 1 + strlen(model) + 1;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((part = topo_mod_alloc(mod, len)) != NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth (void) snprintf(part, len, "%s-%s",
940d71d237794874e18a0eb72f6564821a823517eschrock mfg, model);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth auth = topo_mod_auth(mod, parent);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL,
940d71d237794874e18a0eb72f6564821a823517eschrock auth, part ? part : model, firm, serial);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_free(auth);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
940d71d237794874e18a0eb72f6564821a823517eschrock topo_mod_strfree(mod, part);
940d71d237794874e18a0eb72f6564821a823517eschrock topo_mod_strfree(mod, mfg);
940d71d237794874e18a0eb72f6564821a823517eschrock topo_mod_strfree(mod, model);
940d71d237794874e18a0eb72f6564821a823517eschrock topo_mod_strfree(mod, firm);
940d71d237794874e18a0eb72f6564821a823517eschrock topo_mod_strfree(mod, serial);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (fmri == NULL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_tnode_create: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "hcfmri (%s%d/%s%d) error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_node_name(parent), topo_node_instance(parent),
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth name, i, topo_strerror(topo_mod_errno(mod)));
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dtn = topo_node_bind(mod, parent, name, i, fmri)) == NULL) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (topo_mod_errno(mod) == EMOD_NODE_BOUND) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /*
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson * if disk 0 is already there then we're done
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson nvlist_free(fmri);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (0);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_tnode_create: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "bind (%s%d/%s%d) error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_node_name(parent), topo_node_instance(parent),
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth name, i, topo_strerror(topo_mod_errno(mod)));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_free(fmri);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_free(fmri);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* add the properties of the disk */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (disk_set_props(mod, parent, dtn, dnode) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_tnode_create: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "disk_set_props (%s%d/%s%d) error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_node_name(parent), topo_node_instance(parent),
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth name, i, topo_strerror(topo_mod_errno(mod)));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_node_unbind(dtn);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson *rval = dtn;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdisk_declare(topo_mod_t *mod, tnode_t *parent, dev_di_node_t *dnode,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson tnode_t **childp)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson tnode_t *dtn = NULL;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson int rval;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson rval = disk_tnode_create(mod, parent, dnode, DISK, 0, &dtn);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dtn == NULL) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (rval == 0)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_declare: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "disk_tnode_create error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_strerror(topo_mod_errno(mod)));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* register disk_methods against the disk topo node */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_method_register(mod, dtn, disk_methods) != 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_declare: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "topo_method_register error %s\n",
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_strerror(topo_mod_errno(mod)));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_node_unbind(dtn);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (childp != NULL)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson *childp = dtn;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthint
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_declare_path(topo_mod_t *mod, tnode_t *parent, topo_list_t *listp,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth const char *path)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dnode;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int i;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /*
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Check for match using physical phci (ddn_ppath). Use
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * di_devfs_path_match so generic.vs.non-generic names match.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth for (dnode = topo_list_next(listp); dnode != NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode = topo_list_next(dnode)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_ppath == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth continue;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth for (i = 0; i < dnode->ddn_ppath_count; i++) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (di_devfs_path_match(dnode->ddn_ppath[0], path))
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (disk_declare(mod, parent, dnode, NULL));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_declare_path: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "failed to find disk matching path %s", path);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthint
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_declare_addr(topo_mod_t *mod, tnode_t *parent, topo_list_t *listp,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson const char *addr, tnode_t **childp)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dnode;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int i;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* Check for match using addr. */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth for (dnode = topo_list_next(listp); dnode != NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode = topo_list_next(dnode)) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_target_port == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth continue;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim for (i = 0; i < dnode->ddn_ppath_count; i++) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_target_port[i] != NULL) &&
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim (strncmp(dnode->ddn_target_port[i], addr,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim strcspn(dnode->ddn_target_port[i], ":"))) == 0) {
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson topo_mod_dprintf(mod, "disk_declare_addr: "
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson "found disk matching addr %s", addr);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (disk_declare(mod, parent, dnode,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson childp));
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_declare_addr: "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "failed to find disk matching addr %s", addr);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (1);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson}
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson/*
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 Hanson */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hansonint
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hansondisk_declare_non_enumerated(topo_mod_t *mod, tnode_t *parent, tnode_t **childp)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson{
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (disk_declare(mod, parent, NULL, childp));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim/* di_devlink callback for dev_di_node_add */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_devlink_callback(di_devlink_t dl, void *arg)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth disk_cbdata_t *cbp = (disk_cbdata_t *)arg;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_t *mod = cbp->dcb_mod;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dnode = cbp->dcb_dnode;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth const char *devpath;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *ctds, *slice;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth devpath = di_devlink_path(dl);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dnode == NULL) || (devpath == NULL))
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (DI_WALK_TERMINATE);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* trim the slice off the public name */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (((ctds = strrchr(devpath, '/')) != NULL) &&
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth ((slice = strchr(ctds, 's')) != NULL))
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *slice = '\0';
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* Establish the public /dev name (no slice) */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_lpath = topo_mod_strdup(mod, ctds ? ctds + 1 : devpath);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (ctds && slice)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *slice = 's';
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (DI_WALK_TERMINATE);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic void
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_di_node_free(topo_mod_t *mod, dev_di_node_t *dnode)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int i;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* free the stuff we point to */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (dnode->ddn_devid)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson topo_mod_strfree(mod, dnode->ddn_devid);
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim for (i = 0; i < dnode->ddn_ppath_count; i++) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* topo_mod_strfree does NULL checking. */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_ppath[i]);
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strfree(mod, dnode->ddn_target_port[i]);
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strfree(mod, dnode->ddn_attached_port[i]);
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strfree(mod, dnode->ddn_bridge_port[i]);
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_free(mod, dnode->ddn_ppath,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim dnode->ddn_ppath_count * sizeof (char *));
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_free(mod, dnode->ddn_target_port,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim dnode->ddn_ppath_count * sizeof (char *));
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_free(mod, dnode->ddn_attached_port,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim dnode->ddn_ppath_count * sizeof (char *));
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_free(mod, dnode->ddn_bridge_port,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim dnode->ddn_ppath_count * sizeof (char *));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_dpath);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_lpath);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_mfg);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_model);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_serial);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_firm);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, dnode->ddn_cap);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* free self */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim topo_mod_free(mod, dnode, sizeof (dev_di_node_t));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_di_node_add(di_node_t node, char *devid, disk_cbdata_t *cbp)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_t *mod = cbp->dcb_mod;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dnode;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth di_path_t pnode;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *path;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int mlen;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *minorpath;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *extn = ":a";
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *s;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int64_t *nblocksp;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth uint64_t nblocks;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int *dblksizep;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth uint_t dblksize;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char lentry[MAXPATHLEN];
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim int pathcount;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim int *inq_dtype, itype;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim int i;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (devid) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /*
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 */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson for (dnode = topo_list_next(cbp->dcb_list);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson dnode != NULL; dnode = topo_list_next(dnode)) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (dnode->ddn_devid &&
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson devid_str_compare(dnode->ddn_devid, devid) == 0) {
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim topo_mod_dprintf(mod, "dev_di_node_add: "
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson "already there %s\n", devid);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson return (0);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if ((dnode = topo_mod_zalloc(mod, sizeof (dev_di_node_t))) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (devid) {
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* Establish the devid. */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson dnode->ddn_devid = topo_mod_strdup(mod, devid);
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (dnode->ddn_devid == NULL)
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson goto error;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* Establish the devinfo dpath */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((path = di_devfs_path(node)) == NULL) {
888e055994b8b0dc77b98c53dd97026237caec5dRobert Johnston (void) topo_mod_seterrno(mod, errno);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_dpath = topo_mod_strdup(mod, path);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth di_devfs_path_free(path);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_dpath == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /*
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 *
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 *
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 */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim pathcount = 0;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth pnode = NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth while ((pnode = di_path_client_next_path(node, pnode)) != NULL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth pathcount++;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (pathcount == 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dnode->ddn_ppath =
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_zalloc(mod, sizeof (char *))) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_ppath_count = 1;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dnode->ddn_ppath[0] = topo_mod_strdup(mod,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_dpath)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_target_port = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_attached_port = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_bridge_port = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* There should be only one target port for a devinfo node. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, node,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim SCSI_ADDR_PROP_TARGET_PORT, &s)) == 1) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_target_port[0] =
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strdup(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim scsi_wwnstr_skip_ua_prefix(s))) ==
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, node,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim SCSI_ADDR_PROP_ATTACHED_PORT, &s)) == 1) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* There should be one attached port if any. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_attached_port[0] =
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strdup(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim scsi_wwnstr_skip_ua_prefix(s))) ==
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((di_prop_lookup_strings(DDI_DEV_T_ANY, node,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim SCSI_ADDR_PROP_BRIDGE_PORT, &s)) == 1) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* There should be one bridge port if any. */
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_bridge_port[0] =
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strdup(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim scsi_wwnstr_skip_ua_prefix(s))) ==
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth } else {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim /* processing a scsi_vhci device. */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dnode->ddn_ppath = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim pathcount * sizeof (char *))) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_ppath_count = pathcount;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_target_port = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim pathcount * sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_attached_port = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim pathcount * sizeof (char *))) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_bridge_port = topo_mod_zalloc(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim pathcount * sizeof (char *))) == NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth pnode = NULL;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim pathcount = 0;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth while ((pnode = di_path_client_next_path(node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth pnode)) != NULL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((path = di_path_devfs_path(pnode)) == NULL) {
888e055994b8b0dc77b98c53dd97026237caec5dRobert Johnston (void) topo_mod_seterrno(mod, errno);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dnode->ddn_ppath[pathcount] =
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strdup(mod, path);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth di_devfs_path_free(path);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (dnode->ddn_ppath[pathcount] == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((di_path_prop_lookup_strings(pnode,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim SCSI_ADDR_PROP_TARGET_PORT, &s)) == 1) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_target_port[pathcount] =
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strdup(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim scsi_wwnstr_skip_ua_prefix(s))) ==
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim }
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((di_path_prop_lookup_strings(pnode,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim SCSI_ADDR_PROP_ATTACHED_PORT, &s)) == 1) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_attached_port[pathcount] =
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strdup(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim scsi_wwnstr_skip_ua_prefix(s))) ==
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim }
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((di_path_prop_lookup_strings(pnode,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim SCSI_ADDR_PROP_BRIDGE_PORT, &s)) == 1) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim if ((dnode->ddn_bridge_port[pathcount] =
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim topo_mod_strdup(mod,
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim scsi_wwnstr_skip_ua_prefix(s))) ==
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim NULL)
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth pathcount++;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /*
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).
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type",
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim &inq_dtype) > 0) {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim dnode->ddn_dtype = *inq_dtype;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim itype = (*inq_dtype) & DTYPE_MASK;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if (itype == DTYPE_DIRECT) {
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim mlen = strlen(dnode->ddn_dpath) + strlen(extn) + 1;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if ((minorpath = topo_mod_alloc(mod, mlen)) == NULL)
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim goto error;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim (void) snprintf(minorpath, mlen, "%s%s",
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dnode->ddn_dpath, extn);
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim cbp->dcb_dnode = dnode;
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim (void) di_devlink_walk(cbp->dcb_devhdl, "^dsk/",
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim minorpath, DI_PRIMARY_LINK, cbp,
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim disk_devlink_callback);
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim topo_mod_free(mod, minorpath, mlen);
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim if (dnode->ddn_lpath == NULL) {
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim topo_mod_dprintf(mod, "dev_di_node_add: "
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim "failed to determine logical path");
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim }
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim }
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim } else {
b4879163ff2953ccadc0a01a15e973ad895eb4b7Hyon Kim dnode->ddn_dtype = DTYPE_UNKNOWN;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim /* cache various bits of optional information about the device. */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth INQUIRY_VENDOR_ID, &s) > 0) {
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_mfg = disk_trim_whitespace(mod, s)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth INQUIRY_PRODUCT_ID, &s) > 0) {
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_model = disk_trim_whitespace(mod, s)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth INQUIRY_REVISION_ID, &s) > 0) {
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_firm = disk_trim_whitespace(mod, s)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth INQUIRY_SERIAL_NO, &s) > 0) {
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((dnode->ddn_serial = disk_trim_whitespace(mod, s)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (di_prop_lookup_int64(DDI_DEV_T_ANY, node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "device-nblocks", &nblocksp) > 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nblocks = (uint64_t)*nblocksp;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /*
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * To save kernel memory, the driver may not define
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * "device-dblksize" when its value is default DEV_BSIZE.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (di_prop_lookup_ints(DDI_DEV_T_ANY, node,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "device-dblksize", &dblksizep) > 0)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dblksize = (uint_t)*dblksizep;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth else
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dblksize = DEV_BSIZE; /* default value */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth (void) snprintf(lentry, sizeof (lentry),
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth "%" PRIu64, nblocks * dblksize);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dnode->ddn_cap = topo_mod_strdup(mod, lentry)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth goto error;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim topo_mod_dprintf(mod, "dev_di_node_add: "
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson "adding %s\n", devid ? dnode->ddn_devid : "NULL devid");
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, " "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth " %s\n", dnode->ddn_dpath);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth for (i = 0; i < dnode->ddn_ppath_count; i++) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, " "
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth " %s\n", dnode->ddn_ppath[i]);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_list_append(cbp->dcb_list, dnode);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dctherror:
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_free(mod, dnode);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/* di_walk_node callback for disk_list_gather */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_walk_di_nodes(di_node_t node, void *arg)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
738c43b514a3570e657652233a5a19291a328a28Eric Schrock char *devidstr = NULL;
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson char *s;
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson int *val;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /*
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 */
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson if (di_path_client_next_path(node, NULL) == NULL &&
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson di_prop_lookup_strings(DDI_DEV_T_ANY, node,
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson SCSI_ADDR_PROP_TARGET_PORT, &s) <= 0 &&
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson di_prop_lookup_ints(DDI_DEV_T_ANY, node,
48ea5fa8d82ee7f0003f7299df1e7788786c92a9Stephen Hanson SCSI_ADDR_PROP_TARGET, &val) <= 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (DI_WALK_CONTINUE);
738c43b514a3570e657652233a5a19291a328a28Eric Schrock }
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson (void) di_prop_lookup_strings(DDI_DEV_T_ANY, node,
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson DEVID_PROP_NAME, &devidstr);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* create/find the devid scsi topology node */
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim (void) dev_di_node_add(node, devidstr, arg);
738c43b514a3570e657652233a5a19291a328a28Eric Schrock
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (DI_WALK_CONTINUE);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthint
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_list_gather(topo_mod_t *mod, topo_list_t *listp)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth di_node_t devtree;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth di_devlink_handle_t devhdl;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth disk_cbdata_t dcb;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
738c43b514a3570e657652233a5a19291a328a28Eric Schrock if ((devtree = topo_mod_devinfo(mod)) == DI_NODE_NIL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_list_gather: "
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock "topo_mod_devinfo() failed");
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((devhdl = di_devlink_init(NULL, 0)) == DI_NODE_NIL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_dprintf(mod, "disk_list_gather: "
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock "di_devlink_init() failed");
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (-1);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dcb.dcb_mod = mod;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dcb.dcb_list = listp;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth dcb.dcb_devhdl = devhdl;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
44ed9dbbfa620821ecf59a131462082f628dd0f3Stephen Hanson /* walk the devinfo snapshot looking for disk nodes */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth (void) di_walk_node(devtree, DI_WALK_CLDFIRST, &dcb,
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_walk_di_nodes);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth (void) di_devlink_fini(&devhdl);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthvoid
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kimdev_list_free(topo_mod_t *mod, topo_list_t *listp)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_t *dnode;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth while ((dnode = topo_list_next(listp)) != NULL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /* order of delete/free is important */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_list_delete(listp, dnode);
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim dev_di_node_free(mod, dnode);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth/*
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 *
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * protocol string Supported protocol (currently "scsi")
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * status nvlist Arbitrary protocol-specific information
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * about the current state of the disk.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *
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 *
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * <fault-name> nvlist For each fault named in 'faults', a
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * nvlist describing protocol-specific
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * attributes of the fault.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * This method relies on the libdiskstatus library to query this information.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthstatic int
602ca9ea8f9ce0933f0944601cc5d230e91a950dcthdisk_status(topo_mod_t *mod, tnode_t *nodep, topo_version_t vers,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_t *in_nvl, nvlist_t **out_nvl)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth{
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth disk_status_t *dsp;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth char *devpath, *fullpath;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth size_t pathlen;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth nvlist_t *status;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth int err;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *out_nvl = NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (vers != TOPO_METH_DISK_STATUS_VERSION)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (topo_mod_seterrno(mod, EMOD_VER_NEW));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /*
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 * itself.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (nvlist_lookup_string(in_nvl, "path", &fullpath) == 0) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth devpath = NULL;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth } else {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /*
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Get the /devices path and attempt to open the disk status
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * handle.
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (topo_prop_get_string(nodep, TOPO_PGROUP_IO,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth TOPO_IO_DEV_PATH, &devpath, &err) != 0)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth /*
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth * Note that sizeof(string) includes the terminating NULL byte
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth */
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth pathlen = strlen(devpath) + sizeof ("/devices") +
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth sizeof (PHYS_EXTN) - 1;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((fullpath = topo_mod_alloc(mod, pathlen)) == NULL)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (topo_mod_seterrno(mod, EMOD_NOMEM));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth (void) snprintf(fullpath, pathlen, "/devices%s%s", devpath,
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth PHYS_EXTN);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_strfree(mod, devpath);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((dsp = disk_status_open(fullpath, &err)) == NULL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (devpath)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_free(mod, fullpath, pathlen);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (topo_mod_seterrno(mod, err == EDS_NOMEM ?
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth EMOD_NOMEM : EMOD_METHOD_NOTSUP));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if (devpath)
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth topo_mod_free(mod, fullpath, pathlen);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth if ((status = disk_status_get(dsp)) == NULL) {
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth err = (disk_status_errno(dsp) == EDS_NOMEM ?
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth EMOD_NOMEM : EMOD_METHOD_NOTSUP);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth disk_status_close(dsp);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (topo_mod_seterrno(mod, err));
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth }
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth *out_nvl = status;
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth disk_status_close(dsp);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth return (0);
602ca9ea8f9ce0933f0944601cc5d230e91a950dcth}