03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This plugin-in creates the FRU Hierarchy for the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SUNW,Netra-T12 platform and manages the environmental sensors
03831d35f7499c87d51205817c93e9a8d42c4baestevel * on the platform.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <syslog.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <strings.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libintl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdlib.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <unistd.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <fcntl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <picl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <picltree.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libnvpair.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/param.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <kstat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <config_admin.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbd_ioctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgfrutree.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgenv.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ioccom.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/lw8.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sysevent/dr.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <pthread.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/obpdefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "libdevice.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "picldefs.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define NDEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <assert.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Plugin registration entry points
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void piclfrutree_register(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void piclfrutree_init(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void piclfrutree_fini(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma init(piclfrutree_register)
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic picld_plugin_reg_t my_reg_info = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICLD_PLUGIN_VERSION_1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICLD_PLUGIN_CRITICAL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SUNW_Netra-T12_frutree",
03831d35f7499c87d51205817c93e9a8d42c4baestevel piclfrutree_init,
03831d35f7499c87d51205817c93e9a8d42c4baestevel piclfrutree_fini,
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Log message texts
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DEV_OPEN_FAIL gettext("piclfrutree_init: open of %s failed: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ADD_NODES_FAIL gettext("piclfrutree_init: add_all_nodes failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define GET_ROOT_FAIL gettext("piclfrutree_init: ptree_get_root failed")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ADD_FRUTREE_FAIL gettext("piclfrutree_init: add frutree failed")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define INVALID_PICL_CLASS gettext("add_subtree: invalid picl class 0x%x")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ADD_NODE_FAIL gettext("ptree_create_and_add_node %s failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define GET_NEXT_BY_ROW_FAIL gettext("ptree_get_next_by_row %s failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PROPINFO_FAIL gettext("ptree_init_propinfo %s failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define GET_PROPVAL_FAIL gettext("ptree_get_propval failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DELETE_PROP_FAIL gettext("ptree_delete_prop failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DELETE_NODE_FAIL gettext("ptree_delete_node failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ADD_PROP_FAIL gettext("ptree_create_and_add_prop %s failed: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SGFRU_IOCTL_FAIL gettext("sgfru ioctl 0x%x handle 0x%llx failed: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define LED_IOCTL_FAIL gettext("led ioctl failed: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MALLOC_FAIL gettext("piclfrutree: malloc failed")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define NO_SC_FAIL gettext("piclfrutree: cannot find sc node")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define NO_NODE_FAIL gettext("piclfrutree: cannot find node %s: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define KSTAT_FAIL gettext("piclfrutree: failure accessing kstats")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ADD_TBL_ENTRY_FAIL gettext("piclfrutree: cannot add entry to table")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PROP_LOOKUP_FAIL gettext("piclfrutree: cannot find %s property: %d")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define EM_DI_INIT_FAIL gettext("frutree: di_init failed: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define EM_THREAD_CREATE_FAILED gettext("frutree: pthread_create failed: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define EM_MUTEX_FAIL gettext("frutree: pthread_mutex_lock returned: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define EM_POLL_FAIL gettext("frutree: poll() failed: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DEVCTL_DEVICE_ACQUIRE_FAILED \
03831d35f7499c87d51205817c93e9a8d42c4baestevel gettext("frutree: devctl_device_acquire() failed: %s")
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * PICL property values
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_TRUE "true"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_SYSTEM "system"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_ON "ON"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_OFF "OFF"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_BLINKING "BLINKING"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_FLASHING "FLASHING"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_CHASSIS "chassis"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_AMBIENT "Ambient"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_DIE "Die"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_GREEN "green"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_AMBER "amber"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_OKAY "okay"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_FAILED "failed"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_WARNING "warning"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_DISABLED "disabled"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_UNKNOWN "unknown"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_SELF_REGULATING "self-regulating"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROPVAL_PER_CENT "%"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROP_BANK_STATUS "bank-status"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * PICL property names
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PICL_PROP_LOW_WARNING_THRESHOLD "LowWarningThreshold"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Local defines
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_LINE_SIZE 1024
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_TRIES 4
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_SPEED_UNIT_LEN 20
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_OPERATIONAL_STATUS_LEN 10
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_CONDITION_LEN 10
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_LABEL_LEN 256
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_STATE_LEN 10
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_STATE_SIZE 32
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define LED_PSEUDO_DEV "/devices/pseudo/lw8@0:lw8"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SC_DEV "/platform/ssm@0,0/pci@18,700000/bootbus-controller@4"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SC_DEV_PCIX "/platform/ssm@0,0/pci@18,700000/pci@4/bootbus-controller@3"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define CPU_DEV "/platform/ssm@0,0/SUNW,UltraSPARC-III@%x,0"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define CPU_DEV2 "/platform/ssm@0,0/SUNW,UltraSPARC-III+@%x,0"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define CPU_DEV3C0 "/platform/ssm@0,0/cmp@%x,0/cpu@0"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define CPU_DEV3C1 "/platform/ssm@0,0/cmp@%x,0/cpu@1"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MEMORY_DEV "/platform/ssm@0,0/memory-controller@%x,400000"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IO_DEV "/platform/ssm@0,0/pci@%s"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DISK0_BASE_PATH "/ssm@0,0/pci@18,600000/scsi@2/sd@0,0"
80ab886d233f514d54c2a6bdeb9fdfd951bd6881wesolows#define DISK0_DEV "/platform" DISK0_BASE_PATH
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DISK1_BASE_PATH "/ssm@0,0/pci@18,600000/scsi@2/sd@1,0"
80ab886d233f514d54c2a6bdeb9fdfd951bd6881wesolows#define DISK1_DEV "/platform" DISK1_BASE_PATH
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DISK0_BASE_PATH_PCIX "/ssm@0,0/pci@18,700000/scsi@2/sd@0,0"
80ab886d233f514d54c2a6bdeb9fdfd951bd6881wesolows#define DISK0_DEV_PCIX "/platform" DISK0_BASE_PATH_PCIX
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DISK1_BASE_PATH_PCIX "/ssm@0,0/pci@18,700000/scsi@2/sd@1,0"
80ab886d233f514d54c2a6bdeb9fdfd951bd6881wesolows#define DISK1_DEV_PCIX "/platform" DISK1_BASE_PATH_PCIX
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define TAPE_DEV "/platform/ssm@0,0/pci@18,600000/scsi@2/st@5,0"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define TAPE_DEV_PCIX "/platform/ssm@0,0/pci@18,700000/scsi@2/st@5,0"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DVD_DEV "/platform/ssm@0,0/pci@18,700000/ide@3/sd@0,0"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DVD_DEV_PCIX "/platform/ssm@0,0/pci@18,700000/pci@4/ide@2/sd@0,0"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define CHASSIS_PATH "/frutree/chassis"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define CHASSIS_LOC_PATH "/frutree/chassis/%s"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PROC_LOC_PATH "/frutree/chassis/SB%d/SB%d/P%d"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define PROC_FRU_PATH "/frutree/chassis/SB%d/SB%d/P%d/P%d"
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Calculate safari address to put in CPU_DEV/MEMORY_DEV string based on
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SBx/Py fru path name
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SB_P_TO_SAFARI_ADDR(sbname, pname) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((pname[1] - '0') + (4 * (sbname[2] - '0')))
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SAFARI_ADDR_TO_SB(value) (value >> 2)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SAFARI_ADDR_TO_P(value) (value & 3)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define AP_ID_PREAMBLE "ssm0:N0."
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define AP_ID_PREAMBLE_LEN 8
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define LABEL_PREAMBLE "N0/"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define LABEL_PREAMBLE_LEN 3
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * work out type of fru based on name
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_ECACHE_NODE(name) (name[0] == 'E')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_DIMM_NODE(name) (name[0] == 'D' && name[1] != 'V')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_PROC_NODE(name) (name[0] == 'P' && name[1] != 'S')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_PSU_NODE(name) (name[0] == 'P' && name[1] == 'S')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_SB_NODE(name) (name[0] == 'S' && name[1] == 'B')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_IB_NODE(name) (name[0] == 'I')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_FT_NODE(name) (name[0] == 'F' && name[1] == 'T')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_FAN_NODE(name) (name[0] == 'F' && name[1] != 'T')
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define IS_RP_NODE(name) (name[0] == 'R')
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * rename sgfru driver's node_t to sgfrunode_t to avoid confusion
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define sgfrunode_t node_t
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * disk_led data
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define REMOK_LED "ok_to_remove"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define FAULT_LED "fault"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define POWER_LED "power"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 'struct lw8_disk' contains the per-disk metadata needed to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * manage the current state of one of the internal disks.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 'lw8_disks[]' is an array that contains the metadata
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for N_DISKS disks.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The d_fruname field of 'struct lw8_disk' is static.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * d_plat_path and d_devices_path are aliases for device-paths
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to the disk. They are logically static, as they are computed
03831d35f7499c87d51205817c93e9a8d42c4baestevel * when the disk_leds_thread() thread does its initialization.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * d_state is the most interesting field, as it changes
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dynamically, based on whether the associated disk
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is currently Configured or Unconfigured (by DR). d_state
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is an optimization that minimizes per-disk actions such
03831d35f7499c87d51205817c93e9a8d42c4baestevel * as setting of LEDs and updating the FRU Tree.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * A disk starts in a d_state of DISK_STATE_NOT_INIT
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and moves to DISK_STATE_READY when the disk is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Configured (by DR) and it moves to DISK_STATE_NOT_READY
03831d35f7499c87d51205817c93e9a8d42c4baestevel * when it is Unconfigured (by DR).
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baesteveltypedef enum {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DISK_STATE_NOT_INIT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel DISK_STATE_READY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel DISK_STATE_NOT_READY
03831d35f7499c87d51205817c93e9a8d42c4baestevel} disk_state_t;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstruct lw8_disk {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *d_fruname; /* FRU name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *d_plat_path; /* /platform */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *d_devices_path; /* /devices */
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk_state_t d_state;
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define N_DISKS 2
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct lw8_disk lw8_disks[N_DISKS] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel {"DISK0", NULL, NULL, DISK_STATE_NOT_INIT},
03831d35f7499c87d51205817c93e9a8d42c4baestevel {"DISK1", NULL, NULL, DISK_STATE_NOT_INIT} };
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Duration of inactivity within disk_leds_thread() */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define THR_POLL_PERIOD 5000 /* milliseconds */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic volatile boolean_t disk_leds_thread_ack = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic pthread_t ledsthr_tid;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic pthread_attr_t ledsthr_attr;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic boolean_t ledsthr_created = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t ledsthr_poll_period =
03831d35f7499c87d51205817c93e9a8d42c4baestevel THR_POLL_PERIOD;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic boolean_t g_mutex_init = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic pthread_cond_t g_cv;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic pthread_cond_t g_cv_ack;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic pthread_mutex_t g_mutex;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic volatile boolean_t g_wait_now = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void disk_leds_init(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void disk_leds_fini(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void *disk_leds_thread(void *args);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Tables to convert sgenv information
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic char *hpu_type_table[] = { "", "SSC", "SB", "RP", "FT",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "IB", "PS", "ID"};
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic char *hpu_fru_type_table[] = { "", "SSC", "CPU", "RP", "FT",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "PCIB", "PS", "ID"};
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic char *hpu_part_table[] = { "", "sbbc", "sdc",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ar", "cbh", "dx", "cheetah", "1.5vdc", "3.3vdc",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "5vdc", "12vdc", "output", "current", "board", "sc-app",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "schizo", "fan", "input"};
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic char *hpu_sensor_table[] = { "", "", "current",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "temp", "cooling", "1.5vdc", "1.8vdc", "3.3vdc", "5vdc",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "12vdc", "48vdc", NULL, "2.4vdc"};
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic char *hpu_sensor_class_table[] = { "", "", PICL_CLASS_CURRENT_SENSOR,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_TEMPERATURE_SENSOR, PICL_CLASS_FAN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_VOLTAGE_SENSOR, PICL_CLASS_VOLTAGE_SENSOR,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_VOLTAGE_SENSOR, PICL_CLASS_VOLTAGE_SENSOR,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_VOLTAGE_SENSOR, PICL_CLASS_VOLTAGE_INDICATOR,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL, PICL_CLASS_VOLTAGE_SENSOR};
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic char *hpu_sensor_prop_table[] = { "", "", PICL_PROP_CURRENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_TEMPERATURE, PICL_PROP_FAN_SPEED, PICL_PROP_VOLTAGE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_VOLTAGE, PICL_PROP_VOLTAGE, PICL_PROP_VOLTAGE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_VOLTAGE, PICL_PROP_CONDITION, NULL, PICL_PROP_VOLTAGE};
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic char *hpu_condition_table[] = {"unknown", "okay", "failing",
03831d35f7499c87d51205817c93e9a8d42c4baestevel "failed", "unusable"};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * variables set up in init
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic picl_nodehdl_t frutreeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic picl_nodehdl_t sch = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int init_complete;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int pcix_io = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * forward reference
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_all_nodes(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int remove_subtree(picl_nodehdl_t parh);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_subtree(picl_nodehdl_t parh, fru_hdl_t fruparent);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_picl_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_chassis_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_fru_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_location_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_led_nodes(picl_nodehdl_t nodeh, char *name, int position,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_env_nodes(picl_nodehdl_t nodeh, char *nodename,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_intermediate_nodes(picl_nodehdl_t *nodep, char *labelp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t *tblhdlp, char *slot_name, char *fru_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_intermediate_location(picl_nodehdl_t *nodep, char *labelp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *slot_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_pci_location(picl_nodehdl_t childh, char *parent_addr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char bus_addr, char *slot_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic picl_nodehdl_t find_child_by_name(picl_nodehdl_t parh, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int create_dimm_references(picl_nodehdl_t parh, int dimm_id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t nodeh, picl_prophdl_t tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int create_cpu_references(char *pname, picl_nodehdl_t nodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void post_frudr_event(char *ename, picl_nodehdl_t parenth,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t fruh);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int remove_references(picl_prophdl_t refprop, char *class);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int remove_picl_node(picl_nodehdl_t nodeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sgfrunode_t *get_node_children(fru_hdl_t fruparent, int *num_childrenp);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_prop_ull(picl_nodehdl_t nodeh, uint64_t handle, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_prop_void(picl_nodehdl_t nodeh, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_prop_ref(picl_nodehdl_t nodeh, picl_nodehdl_t value, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_prop_int(picl_nodehdl_t nodeh, int value, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_prop_float(picl_nodehdl_t nodeh, float value, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_prop_charstring(picl_nodehdl_t nodeh, char *value, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void frudr_evhandler(const char *ename, const void *earg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size, void *cookie);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void frumemcfg_evhandler(const char *ename, const void *earg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size, void *cookie);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_sensor_prop(picl_nodehdl_t nodeh, char *class);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_sensor_node(picl_nodehdl_t fruhdl, picl_nodehdl_t lochdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *nodename, char *class, char *prop_class,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl, picl_nodehdl_t *sensorhdlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int create_table(picl_nodehdl_t fruhdl, picl_prophdl_t *tblhdlp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *tbl_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int create_table_entry(picl_prophdl_t tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t refhdl, char *class);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int get_sensor_data(ptree_rarg_t *arg, void *result);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int get_led(char *name, char *ptr, char *result);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int get_led_data(ptree_rarg_t *arg, void *result);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int set_led_data(ptree_warg_t *arg, const void *value);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int get_cpu_status(ptree_rarg_t *arg, void *result);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int add_board_status(picl_nodehdl_t nodeh, char *nodename);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int get_board_status(ptree_rarg_t *arg, void *result);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int get_op_status(ptree_rarg_t *arg, void *result);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define sprintf_buf2(buf, a1, a2) (void) snprintf(buf, sizeof (buf), a1, a2)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define sprintf_buf3(buf, a1, a2, a3) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buf, sizeof (buf), a1, a2, a3)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define sprintf_buf4(buf, a1, a2, a3, a4) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buf, sizeof (buf), a1, a2, a3, a4)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define sprintf_buf5(buf, a1, a2, a3, a4, a5) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buf, sizeof (buf), a1, a2, a3, a4, a5)
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is executed as part of .init when the plugin is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dlopen()ed
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelpiclfrutree_register(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) picld_plugin_register(&my_reg_info);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is the init entry point of the plugin.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * It initializes the /frutree tree
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelpiclfrutree_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_register_handler(PICLEVENT_DR_AP_STATE_CHANGE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel frudr_evhandler, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_register_handler(PICLEVENT_MC_ADDED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel frumemcfg_evhandler, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_register_handler(PICLEVENT_MC_REMOVED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel frumemcfg_evhandler, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel init_complete = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_all_nodes();
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk_leds_init();
03831d35f7499c87d51205817c93e9a8d42c4baestevel init_complete = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODES_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel piclfrutree_fini();
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is the fini entry point of the plugin.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelpiclfrutree_fini(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_unregister_handler(PICLEVENT_DR_AP_STATE_CHANGE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel frudr_evhandler, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_unregister_handler(PICLEVENT_MC_ADDED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel frumemcfg_evhandler, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_unregister_handler(PICLEVENT_MC_REMOVED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel frumemcfg_evhandler, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) remove_subtree(frutreeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk_leds_fini();
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * called from piclfrutree_init() to initialise picl frutree
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_all_nodes(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t rooth;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Get the root node of the PICL tree */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_root(&rooth);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, GET_ROOT_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find sc node so we can create sensor nodes under it */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(SC_DEV, &sch);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * There is a XMITS/PCI-X IO Board assembly implements
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a different path for the the bootbus controller.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(SC_DEV_PCIX, &sch);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel pcix_io = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, NO_SC_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Create and add the root node of the FRU subtree */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(rooth, PICL_NODE_FRUTREE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_PICL, &frutreeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_FRUTREE_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Recursively query the SC and add frutree nodes */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (add_subtree(frutreeh, ROOTPARENT));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Recursive routine to add picl nodes to the frutree. Called from
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add_all_nodes() for the whole frutree at initialisation, and from
03831d35f7499c87d51205817c93e9a8d42c4baestevel * frudr_evhandler() for portions of the frutree on DR insert events
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_subtree(picl_nodehdl_t parh, fru_hdl_t handle)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err, i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int num_children;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfrunode_t *cp, *fruchildren = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find children of the parent node */
03831d35f7499c87d51205817c93e9a8d42c4baestevel fruchildren = get_node_children(handle, &num_children);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fruchildren == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* for each child, add a new picl node */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0, cp = fruchildren; i < num_children; i++, cp++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add the appropriate PICL class
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel childh = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_picl_node(parh, cp, &childh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_NOTNODE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(fruchildren);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Recursively call this function based on has_children hint
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (childh && cp->has_children) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_subtree(childh, cp->handle);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(fruchildren);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(fruchildren);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Recursive routine to remove picl nodes to the frutree. Called from
03831d35f7499c87d51205817c93e9a8d42c4baestevel * piclfrutree_fini() for the whole frutree at termination, and from
03831d35f7499c87d51205817c93e9a8d42c4baestevel * frudr_completion_handler() for portions of the frutree on DR remove events
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelremove_subtree(picl_nodehdl_t parh)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t chdh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_propval_by_name(parh, PICL_PROP_CHILD, &chdh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t)) == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (remove_subtree(chdh) != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (remove_picl_node(parh));
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* NOTREACHED */
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add fru and location nodes with SC_handle property
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (aka, container handle, for frus).
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Return picl_nodehdl of created node in *childp.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_picl_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (sgfrunode->class) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case PSEUDO_FRU_CLASS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (add_chassis_node(parh, sgfrunode, childp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case FRU_CLASS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (add_fru_node(parh, sgfrunode, childp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case LOCATION_CLASS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (add_location_node(parh, sgfrunode, childp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, INVALID_PICL_CLASS, sgfrunode->class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_NOTNODE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create chassis node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_chassis_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t handle = (uint64_t)sgfrunode->handle;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t nodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t devhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(parh, PICL_PROPVAL_CHASSIS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_FRU, &childh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODE_FAIL, PICL_PROPVAL_CHASSIS, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ull(childh, handle, PICL_PROP_SC_HANDLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add devices table to chassis node (may need references
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to led devices)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(childh, &tblhdl, PICL_PROP_DEVICES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_led_nodes(childh, "chassis", LOM_LED_POSITION_FRU, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io)
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(DISK0_DEV_PCIX, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(DISK0_DEV, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodeh = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_location(&nodeh, "DISK0", "disk-slot");
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&nodeh, "DISK0", &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "disk-slot", NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(devhdl, nodeh, PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, devhdl, PICL_CLASS_BLOCK);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io)
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(DISK1_DEV_PCIX, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(DISK1_DEV, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodeh = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_location(&nodeh, "DISK1", "disk-slot");
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&nodeh, "DISK1", &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "disk-slot", NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(devhdl, nodeh, PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, devhdl, PICL_CLASS_BLOCK);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io)
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(TAPE_DEV_PCIX, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(TAPE_DEV, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodeh = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_location(&nodeh, "TAPE", "tape-slot");
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&nodeh, "TAPE", &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "tape-slot", NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(devhdl, nodeh, PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, devhdl, PICL_CLASS_TAPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io)
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(DVD_DEV_PCIX, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(DVD_DEV, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodeh = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_location(&nodeh, "DVD", "dvd-slot");
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&nodeh, "DVD", &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "dvd-slot", NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(devhdl, nodeh, PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, devhdl, PICL_CLASS_CDROM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The XMITS/PCI-X IO Assembly is layed out a bit differently.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "19,600000", '1', "PCI0");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "19,600000", '2', "PCI1");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "19,700000", '1', "PCI2");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "19,700000", '2', "PCI3");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "18,600000", '1', "PCI4");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "18,600000", '2', "PCI5");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "18,700000", '1', "PCI0");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "18,700000", '2', "PCI1");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "19,700000", '1', "PCI2");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "19,700000", '2', "PCI3");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "19,700000", '3', "PCI4");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_pci_location(childh, "18,600000", '1', "PCI5");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create fru node, based on sgfru node "sgfrunode" under parent parh. Return
03831d35f7499c87d51205817c93e9a8d42c4baestevel * picl_nodehdl of created node in *childp.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_fru_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t handle = (uint64_t)sgfrunode->handle;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *nodename = sgfrunode->nodename;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if sgfrunode already there, then just carry on own the tree
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel childh = find_child_by_name(parh, nodename);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (childh != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for frus other than dimms and ecaches, update environmental
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sensors and board status if necessary
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_ECACHE_NODE(nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_DIMM_NODE(nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for dimms we just want status
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_board_status(childh, nodename);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_board_status(childh, nodename);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(childh, PICL_PROP_DEVICES,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &tblhdl, sizeof (tblhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_env_nodes(childh, nodename, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create requested fru node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(parh, nodename, PICL_CLASS_FRU,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &childh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODE_FAIL, nodename, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if sgfru has sent us a valid handle, then there is fruid information.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create the SC_handle, and FRUDateAvailable properties for FRUID.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (handle != -1ULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ull(childh, handle, PICL_PROP_SC_HANDLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_void(childh, PICL_PROP_FRUDATA_AVAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * post fru added event to fru data plugin if this was due to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a dr event - ie post-initialisation
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (init_complete)
03831d35f7499c87d51205817c93e9a8d42c4baestevel post_frudr_event(PICL_FRU_ADDED, parh, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Create empty Devices table - we'll add lines to it as we go along
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(childh, &tblhdl, PICL_PROP_DEVICES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Ecache nodes don't have sensors - just set up FRUType
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_ECACHE_NODE(nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh, "EEPROM", PICL_PROP_FRU_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Dimm nodes don't have sensors - just set up FRUType and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * also reference properties to memory module nodes and OpStatus
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_DIMM_NODE(nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh, "DIMM", PICL_PROP_FRU_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_dimm_references(parh, nodename[1] - '0',
03831d35f7499c87d51205817c93e9a8d42c4baestevel childh, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_board_status(childh, nodename);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * not a Dimm or Ecache node - set up environmental info,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * board status and led info
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_env_nodes(childh, nodename, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_board_status(childh, nodename);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_led_nodes(childh, nodename, LOM_LED_POSITION_FRU, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create location node, based on sgfru node "sgfrunode" under parent parh.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Return picl_nodehdl of created node in *childp.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_location_node(picl_nodehdl_t parh, sgfrunode_t *sgfrunode,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *childp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t handle = (uint64_t)sgfrunode->handle;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *labelp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char label[MAX_LABEL_LEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *ptr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * strip "N0/" off the label if present (hang-over from wildcat)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(sgfrunode->location_label, LABEL_PREAMBLE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel LABEL_PREAMBLE_LEN) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(label, &sgfrunode->location_label[
03831d35f7499c87d51205817c93e9a8d42c4baestevel LABEL_PREAMBLE_LEN], sizeof (label));
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(label, &sgfrunode->location_label[0],
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (label));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * some of the locations returned by sgfru are actually of the form
03831d35f7499c87d51205817c93e9a8d42c4baestevel * XX/YY/ZZ - we need to create multiple levels in the picl tree for
03831d35f7499c87d51205817c93e9a8d42c4baestevel * these.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel labelp = label;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while ((ptr = strchr(labelp, '/')) != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * null end of this section of label
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel *ptr = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add intermediate nodes - parh will point to the created node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_PROC_NODE(labelp)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&parh, labelp, &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "cpu", "PROC");
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&parh, labelp, &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if processor node, then create links to associated cpu node
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and OpStatus property
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_PROC_NODE(labelp)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_cpu_references(labelp, parh, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_board_status(parh, labelp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel labelp = ptr + 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * set back to "/"
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel *ptr = '/';
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if node already there, then just carry on down the tree
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel childh = find_child_by_name(parh, labelp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (childh != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now just have the final level of the node left. First create it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(parh, labelp, PICL_CLASS_LOCATION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &childh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODE_FAIL, labelp, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if sgfru has sent us a valid handle, then there is fruid information.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create the SC_handle property for FRUID.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (handle != -1ULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ull(childh, handle, PICL_PROP_SC_HANDLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* create label property for location class */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh, labelp, PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* create SlotType property where appropriate */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_ECACHE_NODE(sgfrunode->nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "ecache", PICL_PROP_SLOT_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For Ecache, don't need to add environmental info
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so return here
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (IS_DIMM_NODE(sgfrunode->nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh, "memory-module",
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_SLOT_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For Dimm, don't need to add environmental info
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so return here
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (IS_SB_NODE(sgfrunode->nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh, "system-board",
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_SLOT_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (IS_PSU_NODE(sgfrunode->nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh, "power-supply",
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_SLOT_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (IS_FT_NODE(sgfrunode->nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(childh, "fan-tray",
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_SLOT_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add devices table to location node (may need
03831d35f7499c87d51205817c93e9a8d42c4baestevel * references to led devices)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(childh, &tblhdl, PICL_PROP_DEVICES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_led_nodes(childh, labelp, LOM_LED_POSITION_LOCATION, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *childp = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * remove an individual picl node - called from remove_subtree()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * also removes any sensor nodes pointed at by Devices table
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelremove_picl_node(picl_nodehdl_t nodeh)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t nextprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t refprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char class[PICL_CLASSNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * first scan Devices table so we can find any sensor nodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we need to delete as well
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(nodeh, PICL_PROP_DEVICES,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &tblhdl, sizeof (tblhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If Devices table present, then read first column.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Devices table may be empty so don't treat this as an error
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_get_next_by_row(tblhdl, &nextprop) == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find second column */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_row(nextprop, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, GET_NEXT_BY_ROW_FAIL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_DEVICES, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * walk down second column (ref ptr)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * deleting the referenced nodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval(nextprop, &refprop,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (refprop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, GET_PROPVAL_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * don't delete memory-module nodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or cpu nodes (they weren't created
03831d35f7499c87d51205817c93e9a8d42c4baestevel * by this plugin)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(refprop,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_CLASSNAME, class, sizeof (class));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_STALEHANDLE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if another plugin has already deleted the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * node for us then that is ok
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_col(nextprop,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_CLASSNAME, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(class, PICL_CLASS_MEMORY_MODULE) == 0 ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel strcmp(class, PICL_CLASS_CPU) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * but - do need to remove _fru_parent
03831d35f7499c87d51205817c93e9a8d42c4baestevel * property and Environment table (for cpu)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = remove_references(refprop, class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sensor node - need to delete it
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_node(refprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DELETE_PROP_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_node(refprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_col(nextprop, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now we can remove the frutree node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_node(nodeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DELETE_PROP_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_node(nodeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_child_pci_references(picl_nodehdl_t nodeh, picl_prophdl_t tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t devnodeh)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = PICL_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t childnodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char class[PICL_CLASSNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_propval_by_name(devnodeh, PICL_PROP_CHILD, &childnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (childnodeh)) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(childnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_CLASSNAME, class, sizeof (class));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(childnodeh, nodeh, PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, childnodeh, class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_child_pci_references(nodeh, tblhdl, childnodeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(childnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER, &childnodeh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = PICL_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_pci_location(picl_nodehdl_t childh, char *parent_addr, char bus_addr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *slot_name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int got_one = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t nodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t devnodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t devhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char addr[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char parent_path[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char class[PICL_CLASSNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * search for any device nodes whose BUS_ADDR or UNIT_ADDRESS
03831d35f7499c87d51205817c93e9a8d42c4baestevel * are appropriate for this pci slot
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(parent_path, IO_DEV, parent_addr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_node_by_path(parent_path, &devhdl) == PICL_SUCCESS &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_get_propval_by_name(devhdl, PICL_PROP_CHILD, &devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (devnodeh)) == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (!got_one) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_BUS_ADDR, addr, sizeof (addr));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS && addr[0] == bus_addr &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (addr[1] == ',' || addr[1] == '\0')) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel got_one = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_UNIT_ADDRESS, addr, sizeof (addr));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS && addr[0] == bus_addr &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (addr[1] == ',' || addr[1] == '\0')) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel got_one = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER, &devnodeh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodeh = childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (got_one == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * no devnodes for this slot. Create location node but
03831d35f7499c87d51205817c93e9a8d42c4baestevel * no fru node (empty slot)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (add_intermediate_location(&nodeh, slot_name, "pci"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we've got the first devnode for this slot. Create the fru node
03831d35f7499c87d51205817c93e9a8d42c4baestevel * then walk along other nodes looking for further devnodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&nodeh, slot_name, &tblhdl, "pci", NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (((err = ptree_get_propval_by_name(devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_BUS_ADDR, addr, sizeof (addr))) ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_SUCCESS && addr[0] == bus_addr &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (addr[1] == ',' || addr[1] == '\0')) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((err = ptree_get_propval_by_name(devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_UNIT_ADDRESS, addr, sizeof (addr))) ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_SUCCESS && addr[0] == bus_addr &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (addr[1] == ',' || addr[1] == '\0'))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_CLASSNAME, class, sizeof (class));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(devnodeh, nodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, devnodeh, class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_child_pci_references(nodeh, tblhdl, devnodeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(devnodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER, &devnodeh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = PICL_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add intermediate location into frutree (ie a location that we know
03831d35f7499c87d51205817c93e9a8d42c4baestevel * exists but sgfru doesn't)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_intermediate_location(picl_nodehdl_t *nodep, char *labelp, char *slot_name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t intermediate;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char parent_name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(*nodep, labelp, PICL_CLASS_LOCATION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &intermediate);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODE_FAIL, labelp, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create label property for location class
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(intermediate, labelp, PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add devices table to location node (may need references to led
03831d35f7499c87d51205817c93e9a8d42c4baestevel * devices)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(intermediate, &tblhdl, PICL_PROP_DEVICES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scapp knows FANs 0 and 1 on IB as FAN8 and FAN9
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(*nodep, PICL_PROP_NAME, parent_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (parent_name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(labelp, "FAN0") == 0 && strcmp(parent_name, "IB6") == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_led_nodes(intermediate, "FAN8",
03831d35f7499c87d51205817c93e9a8d42c4baestevel LOM_LED_POSITION_LOCATION, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else if (strcmp(labelp, "FAN1") == 0 && strcmp(parent_name, "IB6") == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_led_nodes(intermediate, "FAN9",
03831d35f7499c87d51205817c93e9a8d42c4baestevel LOM_LED_POSITION_LOCATION, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_led_nodes(intermediate, labelp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel LOM_LED_POSITION_LOCATION, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (slot_name) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(intermediate, slot_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_SLOT_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel *nodep = intermediate;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * adds an intermediate location/fru pair into frutree
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_intermediate_nodes(picl_nodehdl_t *nodep, char *labelp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t *tblhdlp, char *slot_name, char *fru_name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t intermediate;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t intermediate2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create intermediate location node (unless it has already been
03831d35f7499c87d51205817c93e9a8d42c4baestevel * created)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel intermediate = find_child_by_name(*nodep, labelp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (intermediate == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel intermediate = *nodep;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_location(&intermediate, labelp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create intermediate fru node (unless it has already been
03831d35f7499c87d51205817c93e9a8d42c4baestevel * created)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel intermediate2 = find_child_by_name(intermediate, labelp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (intermediate2 == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * need to create intermediate fru node node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(intermediate, labelp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_FRU, &intermediate2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODE_FAIL, labelp, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Create empty Devices table
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(intermediate2, tblhdlp, PICL_PROP_DEVICES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fru_name) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(intermediate2, fru_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_FRU_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(intermediate2,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_DEVICES, tblhdlp, sizeof (*tblhdlp));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel *nodep = intermediate2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * need to remove _fru_parent property and Environment table (for cpu)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelremove_references(picl_prophdl_t refprop, char *class)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t platprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(refprop, PICL_REFPROP_FRU_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &platprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_prop(platprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DELETE_PROP_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_prop(platprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(class, PICL_CLASS_CPU) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(refprop, PICL_PROP_ENV, &platprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * multi-core cpu is setup with only one cpu having
03831d35f7499c87d51205817c93e9a8d42c4baestevel * env table so ignore PICL_PROPNOTFOUND error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_PROPNOTFOUND) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_ENV, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_prop(platprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DELETE_PROP_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_prop(platprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * subroutine for various functions. Finds immediate child of parh with
03831d35f7499c87d51205817c93e9a8d42c4baestevel * requested name if present. Otherwise returns NULL.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic picl_nodehdl_t
03831d35f7499c87d51205817c93e9a8d42c4baestevelfind_child_by_name(picl_nodehdl_t parh, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t nodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char nodename[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parh, PICL_PROP_CHILD,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &nodeh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(nodeh, PICL_PROP_NAME, nodename,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (nodename));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, nodename) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (nodeh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(nodeh, PICL_PROP_PEER,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &nodeh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelcreate_dimm_references(picl_nodehdl_t parh, int dimm_id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t nodeh, picl_prophdl_t tblhdl)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t memctlhdl = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t memgrphdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t memhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char sbname[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char pname[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char bname[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t parentfruh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t parentloch;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create reference properties for memory nodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - first find names of ancestor frus - ie "SBx/Py/Bz"
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parh, PICL_PROP_PARENT, &parentfruh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentfruh, PICL_PROP_NAME,
03831d35f7499c87d51205817c93e9a8d42c4baestevel bname, sizeof (bname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_NAME, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentfruh, PICL_PROP_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &parentloch, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentloch, PICL_PROP_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &parentfruh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentfruh, PICL_PROP_NAME,
03831d35f7499c87d51205817c93e9a8d42c4baestevel pname, sizeof (pname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_NAME, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentfruh, PICL_PROP_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &parentloch, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentloch, PICL_PROP_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &parentfruh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentfruh, PICL_PROP_NAME, sbname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sbname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_NAME, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ok - we've now got name of system board node in sbname and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * name of processor node in pname.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now find corresponding memory-controller node if present
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(name, MEMORY_DEV, SB_P_TO_SAFARI_ADDR(sbname, pname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(name, &memctlhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now find corresponding memory-module-group node if present
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memctlhdl, PICL_PROP_CHILD, &memgrphdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check if this is the right bank - if not move on to sibling
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memgrphdl, PICL_PROP_ID,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &id, sizeof (int));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bname[1] != id + '0') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memgrphdl, PICL_PROP_PEER,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &memgrphdl, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memgrphdl, PICL_PROP_ID,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &id, sizeof (int));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bname[1] != id + '0')
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now find corresponding memory-module node if present
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memgrphdl, PICL_PROP_CHILD, &memhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for each DIMM set up links with matching memory-module node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memhdl, PICL_PROP_ID,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &id, sizeof (int));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS && dimm_id == id) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(memhdl, nodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, memhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_MEMORY_MODULE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memhdl, PICL_PROP_PEER,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &memhdl, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelcreate_cpu_references(char *pname, picl_nodehdl_t nodeh, picl_prophdl_t tblhdl)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t sensorhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t parentloch;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t parentfruh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t cpuhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t cpuhdl1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t envtblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t prophdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char sbname[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(nodeh, PICL_PROP_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &parentloch, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentloch, PICL_PROP_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &parentfruh, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentfruh, PICL_PROP_NAME, sbname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sbname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_NAME, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find corresponding cpu node if present. Note, this code will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * attempt to find a corresponding cpu node, by searching for devices
03831d35f7499c87d51205817c93e9a8d42c4baestevel * of the types /platform/ssm@0,0/SUNW,UltraSPARC-III+@%x,0,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * /platform/ssm@0,0/SUNW,UltraSPARC-III@%x,0 or
03831d35f7499c87d51205817c93e9a8d42c4baestevel * /platform/ssm@0,0/cmp@%x,0/cpu@0 or 1. If we can not find
03831d35f7499c87d51205817c93e9a8d42c4baestevel * any such device, we return PICL_SUCCESS such that we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * continue the construction of the remaining part of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * tree. We first check for UltraSPARC-III. If we do not
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find such a device we check for UltraSPARC-III+. If
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we are unsuccesful again we try one of the jaguar cores
03831d35f7499c87d51205817c93e9a8d42c4baestevel * /platform/ssm@0,0/cmp@%x,0/cpu@. If we do not find the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * first one, there's no point in continuing and we just
03831d35f7499c87d51205817c93e9a8d42c4baestevel * return PICL_SUCCESS. Similarly if we find one core
03831d35f7499c87d51205817c93e9a8d42c4baestevel * but not the other, something must be wrong, so we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * again just return PICL_SUCCESS without creating any
03831d35f7499c87d51205817c93e9a8d42c4baestevel * references.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(name, CPU_DEV, SB_P_TO_SAFARI_ADDR(sbname, pname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(name, &cpuhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(name, CPU_DEV2,
03831d35f7499c87d51205817c93e9a8d42c4baestevel SB_P_TO_SAFARI_ADDR(sbname, pname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(name, &cpuhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check for jaguar cores */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(name, CPU_DEV3C1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel SB_P_TO_SAFARI_ADDR(sbname, pname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(name, &cpuhdl1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* add fru parent reference for the second core */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(cpuhdl1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_REFPROP_FRU_PARENT, &prophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(cpuhdl1, nodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, cpuhdl1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_CPU);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(name, CPU_DEV3C0,
03831d35f7499c87d51205817c93e9a8d42c4baestevel SB_P_TO_SAFARI_ADDR(sbname, pname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(name, &cpuhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now create reference properties
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(cpuhdl, PICL_REFPROP_FRU_PARENT, &prophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(cpuhdl, nodeh, PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, cpuhdl, PICL_CLASS_CPU);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create Environment table on cpu node - with Die and Ambient
03831d35f7499c87d51205817c93e9a8d42c4baestevel * temperature sensors if present. If already there, delete and start
03831d35f7499c87d51205817c93e9a8d42c4baestevel * again
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(cpuhdl, PICL_PROP_ENV, &prophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_prop(prophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_prop(prophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(cpuhdl, &envtblhdl, PICL_PROP_ENV);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io)
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(name, "%s/%s_t_cheetah%d@0", SC_DEV_PCIX, sbname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pname[1] - '0'));
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(name, "%s/%s_t_cheetah%d@0", SC_DEV, sbname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pname[1] - '0'));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(name, &sensorhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(envtblhdl, sensorhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_TEMPERATURE_SENSOR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io)
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(name, "%s/%s_t_ambient%d@0", SC_DEV_PCIX, sbname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pname[1] - '0'));
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(name, "%s/%s_t_ambient%d@0", SC_DEV, sbname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pname[1] - '0'));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(name, &sensorhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (create_table_entry(envtblhdl, sensorhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_TEMPERATURE_SENSOR));
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * subroutine of add_subtree - get a list of children of a parent node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sgfrunode_t *
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_node_children(fru_hdl_t fruparent, int *num_childrenp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int max_children, i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfrunode_t *fruchildren = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_info_t child_info;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int frufd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Open the sgfru pseudo dev
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((frufd = open(FRU_PSEUDO_DEV, O_RDWR, 0)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DEV_OPEN_FAIL, FRU_PSEUDO_DEV, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 1; i <= MAX_TRIES; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_children = i * MAX_NODE_CHILDREN;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((fruchildren = calloc(max_children,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sgfrunode_t))) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(frufd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, MALLOC_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_info.fru_hdl = fruparent;
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_info.fru_cnt = max_children;
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_info.frus = (void *)fruchildren;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(frufd, SGFRU_GETCHILDLIST, &child_info) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * got them - return success
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(frufd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *num_childrenp = child_info.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (fruchildren);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(fruchildren);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if ENOMEM, need to calloc more space - so go round loop again
03831d35f7499c87d51205817c93e9a8d42c4baestevel * otherwise fail
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (errno != ENOMEM) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(frufd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, SGFRU_IOCTL_FAIL, SGFRU_GETCHILDLIST,
03831d35f7499c87d51205817c93e9a8d42c4baestevel fruparent, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(frufd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, MALLOC_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Creates an unsigned longlong property for a given PICL node */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_prop_ull(picl_nodehdl_t nodeh, uint64_t handle, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t proph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_UNSIGNED_INT, PICL_READ, sizeof (unsigned long long),
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_SC_HANDLE, NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, &handle, &proph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Creates a void property for a given PICL node */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_prop_void(picl_nodehdl_t nodeh, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t proph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_VOID, PICL_READ, 0, PICL_PROP_FRUDATA_AVAIL, NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Creates a reference property for a given PICL node */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_prop_ref(picl_nodehdl_t nodeh, picl_nodehdl_t value, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t proph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t), name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, &value, &proph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Creates an integer property for a given PICL node */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_prop_int(picl_nodehdl_t nodeh, int value, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t proph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_INT, PICL_READ, sizeof (int), name, NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, &value, &proph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Creates an integer property for a given PICL node */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_prop_float(picl_nodehdl_t nodeh, float value, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t proph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_FLOAT, PICL_READ, sizeof (float), name, NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, &value, &proph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Creates a charstring property for a given PICL node */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_prop_charstring(picl_nodehdl_t nodeh, char *value, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t proph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_CHARSTRING, PICL_READ, strlen(value) + 1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel name, NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, value, &proph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* create an entry in the specified table */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelcreate_table_entry(picl_prophdl_t tblhdl, picl_nodehdl_t refhdl, char *class)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t prop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t prophdl[2];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* first column is class */
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.version = PTREE_PROPINFO_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.type = PICL_PTYPE_CHARSTRING;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.accessmode = PICL_READ;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.size = PICL_CLASSNAMELEN_MAX;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.read = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.write = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(prop.piclinfo.name, PICL_PROP_CLASS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (prop.piclinfo.name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_prop(&prop, class, &prophdl[0]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_TBL_ENTRY_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* second column is refernce property */
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.version = PTREE_PROPINFO_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.type = PICL_PTYPE_REFERENCE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.accessmode = PICL_READ;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.size = sizeof (picl_nodehdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.read = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.write = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(prop.piclinfo.name, "_%s_", class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_prop(&prop, &refhdl, &prophdl[1]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_TBL_ENTRY_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* add row to table */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_add_row_to_table(tblhdl, 2, prophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_TBL_ENTRY_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* create an empty table property */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelcreate_table(picl_nodehdl_t fruhdl, picl_prophdl_t *tblhdlp, char *tbl_name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t prop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblprophdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_table(tblhdlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, tbl_name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.version = PTREE_PROPINFO_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.type = PICL_PTYPE_TABLE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.accessmode = PICL_READ;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.piclinfo.size = sizeof (picl_prophdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.read = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop.write = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(prop.piclinfo.name, tbl_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (prop.piclinfo.name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(fruhdl, &prop, tblhdlp, &tblprophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, tbl_name, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelfrudr_add_subtree(picl_nodehdl_t parh)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_hdl_t sgfruhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_propval_by_name(parh, PICL_PROP_SC_HANDLE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sgfruhdl, sizeof (sgfruhdl)) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) add_subtree(parh, sgfruhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* event completion handler for PICL_FRU_ADDED/PICL_FRU_REMOVED events */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelfrudr_completion_handler(char *ename, void *earg, size_t size)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t fruh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t parh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(ename, PICL_FRU_REMOVED) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now frudata has been notified that the node is to be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * removed, we can actually remove it
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel fruh = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_lookup_uint64(earg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICLEVENTARG_FRUHANDLE, &fruh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fruh != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) remove_subtree(fruh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now repopulate the frutree with current data.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel parh = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) nvlist_lookup_uint64(earg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICLEVENTARG_PARENTHANDLE, &parh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (parh != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel frudr_add_subtree(parh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(earg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(earg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(ename);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Post the PICL_FRU_ADDED/PICL_FRU_REMOVED event
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelpost_frudr_event(char *ename, picl_nodehdl_t parenth, picl_nodehdl_t fruh)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_t *nvl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *ev_name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ev_name = strdup(ename);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ev_name == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, NULL)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(ev_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (parenth != 0L &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_add_uint64(nvl, PICLEVENTARG_PARENTHANDLE, parenth)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(ev_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fruh != 0L &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_add_uint64(nvl, PICLEVENTARG_FRUHANDLE, fruh)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(ev_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_post_event(ev_name, nvl, sizeof (nvl),
03831d35f7499c87d51205817c93e9a8d42c4baestevel frudr_completion_handler) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(ev_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank/*
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * updates the picl node 'loc' with the new fru handle (PICL_PROP_SC_HANDLE)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * (helper function for frudr_evhandler, when a stale fru handle is
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * detected)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank */
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrankstatic void
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrankupdate_fru_hdl(picl_nodehdl_t loc, fru_hdl_t newsgfruhdl)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank{
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank picl_prophdl_t schproph;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank int err;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank err = ptree_get_prop_by_name(loc, PICL_PROP_SC_HANDLE, &schproph);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (err == PICL_SUCCESS) {
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (ptree_delete_prop(schproph) == PICL_SUCCESS) {
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank (void) ptree_destroy_prop(schproph);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank }
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank }
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank (void) add_prop_ull(loc, (uint64_t)newsgfruhdl, PICL_PROP_SC_HANDLE);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank}
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank/*
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * Get the fru handle of loc by iterating through the parent's children.
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * Sets fruhdl and returns PICL_SUCCESS unless an error is encountered.
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank */
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrankstatic int
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrankget_fruhdl_from_parent(picl_nodehdl_t loc, fru_hdl_t *fruhdl)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank{
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank picl_nodehdl_t parlocnodeh;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank fru_hdl_t parsgfruhdl;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank sgfrunode_t *cp;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank sgfrunode_t *fruchildren;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank char nodename[PICL_PROPNAMELEN_MAX];
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank int err;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank int num_children;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank int i;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank err = ptree_get_propval_by_name(loc, PICL_PROP_NAME, (void *)nodename,
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank PICL_PROPNAMELEN_MAX);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (err != PICL_SUCCESS)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank return (err);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank err = ptree_get_propval_by_name(loc, PICL_PROP_PARENT, &parlocnodeh,
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank sizeof (picl_nodehdl_t));
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (err != PICL_SUCCESS)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank return (err);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if ((err = ptree_get_propval_by_name(parlocnodeh, PICL_PROP_SC_HANDLE,
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank &parsgfruhdl, sizeof (parsgfruhdl))) != PICL_SUCCESS)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank return (err);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank /* find children of the parent node */
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank fruchildren = get_node_children(parsgfruhdl, &num_children);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (fruchildren == NULL)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank return (PICL_FAILURE);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank for (i = 0, cp = fruchildren; i < num_children; i++, cp++) {
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank /* find the child we're interested in */
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (strcmp(cp->nodename, nodename) == 0) {
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank *fruhdl = cp->handle;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank free(fruchildren);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank return (PICL_SUCCESS);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank }
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank }
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank free(fruchildren);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank return (PICL_FAILURE);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank}
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * handle EC_DR picl events
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelfrudr_evhandler(const char *ename, const void *earg, size_t size, void *cookie)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_t *nvlp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *dtype;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *ap_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *hint;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char path[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t fruh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t locnodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_hdl_t sgfruhdl;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank fru_hdl_t sgfruhdl_from_parent;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(ename, PICLEVENT_DR_AP_STATE_CHANGE) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (nvlist_unpack((char *)earg, size, &nvlp, NULL))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (nvlist_lookup_string(nvlp, PICLEVENTARG_DATA_TYPE, &dtype)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(dtype, PICLEVENTARG_PICLEVENT_DATA) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (nvlist_lookup_string(nvlp, PICLEVENTARG_AP_ID, &ap_id)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (nvlist_lookup_string(nvlp, PICLEVENTARG_HINT, &hint)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(ap_id, AP_ID_PREAMBLE, AP_ID_PREAMBLE_LEN) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * OK - so this is an EC_DR event - let's handle it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(path, CHASSIS_LOC_PATH, &ap_id[AP_ID_PREAMBLE_LEN]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * special case - SSC arrival means that SSC has been reset - we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * need to flush the cached sgfru handles
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(&ap_id[AP_ID_PREAMBLE_LEN], "SSC1") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t chdh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t peerh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t parh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int got_peer;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char label[MAX_LABEL_LEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfrunode_t *sgfruchassisp = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int num_children;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t schproph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find existing chassis node */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_node_by_path(CHASSIS_PATH, &parh) !=
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find new chassis sgfru node */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfruchassisp = get_node_children(ROOTPARENT, &num_children);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfruchassisp == NULL || num_children != 1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* update chassis SC_HANDLE property */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(parh, PICL_PROP_SC_HANDLE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &schproph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_prop(schproph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_prop(schproph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ull(parh, sgfruchassisp->handle,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_SC_HANDLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * remove all subtrees except DISK, TAPE, DVD and PCI subtrees
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_propval_by_name(parh, PICL_PROP_CHILD, &chdh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t)) == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_propval_by_name(chdh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER, &peerh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t)) != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel got_peer = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel got_peer = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(chdh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LABEL, label, sizeof (label));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(label, "DISK",
03831d35f7499c87d51205817c93e9a8d42c4baestevel strlen("DISK")) != 0 &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel strncmp(label, "TAPE",
03831d35f7499c87d51205817c93e9a8d42c4baestevel strlen("TAPE")) != 0 &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel strncmp(label, "PCI",
03831d35f7499c87d51205817c93e9a8d42c4baestevel strlen("PCI")) != 0 &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel strncmp(label, "DVD",
03831d35f7499c87d51205817c93e9a8d42c4baestevel strlen("DVD")) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) remove_subtree(chdh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (got_peer == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel chdh = peerh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* add new subtrees */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) add_subtree(parh, sgfruchassisp->handle);
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(sgfruchassisp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_node_by_path(path, &locnodeh) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_propval_by_name(locnodeh, PICL_PROP_SC_HANDLE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sgfruhdl, sizeof (sgfruhdl)) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * now either add or delete the fru node as appropriate. If no
03831d35f7499c87d51205817c93e9a8d42c4baestevel * hint, treat as insert - add_subtree will update the tree if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * necessary.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(hint, DR_HINT_REMOVE) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_propval_by_name(locnodeh, PICL_PROP_CHILD,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &fruh, sizeof (picl_nodehdl_t)) != PICL_PROPNOTFOUND) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fru was there - but has gone away
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel post_frudr_event(PICL_FRU_REMOVED, locnodeh, fruh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fru has been inserted (or may need to update)
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank *
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * sgfruhdl may be stale due to hotplugging. We check this
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * by getting the fru_hdl_t from the parent's children
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * and compare it to the cached value in sgfruhdl. If we
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * have a stale handle, we update the cached value and
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank * use it in the call to add_subtree.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (get_fruhdl_from_parent(locnodeh, &sgfruhdl_from_parent) ==
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank PICL_SUCCESS) {
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank if (sgfruhdl != sgfruhdl_from_parent) {
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank update_fru_hdl(locnodeh, sgfruhdl_from_parent);
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank sgfruhdl = sgfruhdl_from_parent;
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank }
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank }
768a4bffc5445b9add9ec1bbbcfdd96aafd3f957jfrank
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) add_subtree(locnodeh, sgfruhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * handle memcfg picl events - need to update reference properties
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelfrumemcfg_evhandler(const char *ename, const void *earg, size_t size,
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *cookie)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t nodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t lochdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t fruhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t memgrphdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t memhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblproph;
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_t *nvlp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char addr[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char bname[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t banklochdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t bankfruhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char label[MAX_LABEL_LEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *ptr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf[MAX_LINE_SIZE];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(ename, PICLEVENT_MC_ADDED) != 0 &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel strcmp(ename, PICLEVENT_MC_REMOVED) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find corresponding frutree dimm nodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (nvlist_unpack((char *)earg, size, &nvlp, NULL))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (nvlist_lookup_uint64(nvlp, PICLEVENTARG_NODEHANDLE, &nodeh)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel nvlist_free(nvlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(nodeh, PICL_PROP_UNIT_ADDRESS, addr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (addr));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptr = strchr(addr, ',');
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptr == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel *ptr = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = strtol(addr, NULL, 16);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf5(buf, PROC_FRU_PATH, SAFARI_ADDR_TO_SB(value),
03831d35f7499c87d51205817c93e9a8d42c4baestevel SAFARI_ADDR_TO_SB(value), SAFARI_ADDR_TO_P(value),
03831d35f7499c87d51205817c93e9a8d42c4baestevel SAFARI_ADDR_TO_P(value));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(buf, &fruhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(fruhdl, PICL_PROP_CHILD,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &banklochdl, sizeof (banklochdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * walk through the DIMM locations
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(banklochdl, PICL_PROP_CHILD,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &bankfruhdl, sizeof (bankfruhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_bank;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(bankfruhdl, PICL_PROP_CHILD,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &lochdl, sizeof (lochdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_bank;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(lochdl, PICL_PROP_CHILD,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &fruhdl, sizeof (fruhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * this is a frutree dimm node corresponding to the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * memory controller that has been added/deleted
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - so create/delete reference properties
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(ename, PICLEVENT_MC_ADDED) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find bank name
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(fruhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_DEVICES, &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (tblhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(lochdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LABEL, label, sizeof (label));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(bankfruhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_NAME, bname, sizeof (bname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find memory group node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(nodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_CHILD, &memgrphdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (memgrphdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check if this is the right bank - if not
03831d35f7499c87d51205817c93e9a8d42c4baestevel * move on to sibling
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memgrphdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_ID, &id, sizeof (id));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bname[1] != id + '0') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err =
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_get_propval_by_name(memgrphdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER, &memgrphdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (memgrphdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err =
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_get_propval_by_name(memgrphdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_ID, &id, sizeof (id));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bname[1] != id + '0')
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * got the right bank - now create appropriate
03831d35f7499c87d51205817c93e9a8d42c4baestevel * link
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memgrphdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_CHILD, &memhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (memhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_ID, &id, sizeof (id));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_dimm;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (label[1] == ('0' + id)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(memhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel fruhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel memhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_MEMORY_MODULE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(memhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &memhdl, sizeof (memhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_PROPNOTFOUND)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(ename, PICLEVENT_MC_REMOVED) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * XXX - no mechanism for deleting row - so
03831d35f7499c87d51205817c93e9a8d42c4baestevel * delete whole tabel and start again
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(fruhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_DEVICES, &tblproph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_prop(tblproph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_prop(tblproph);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(fruhdl, &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_DEVICES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevelnext_dimm:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(lochdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER, &lochdl, sizeof (lochdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_PROPNOTFOUND)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevelnext_bank:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(banklochdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_PEER, &banklochdl, sizeof (banklochdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_PROPNOTFOUND)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We don't get an event to say that cpu nodes have been added/
03831d35f7499c87d51205817c93e9a8d42c4baestevel * deleted (in fact as things stand they are never deleted). However
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we know that all cpus must be configured before the MC_ADDED event
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we are handling here. So if the cpu links haven't been set up yet
03831d35f7499c87d51205817c93e9a8d42c4baestevel * then we do it now.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(ename, PICLEVENT_MC_ADDED) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(buf, PROC_LOC_PATH, SAFARI_ADDR_TO_SB(value),
03831d35f7499c87d51205817c93e9a8d42c4baestevel SAFARI_ADDR_TO_SB(value), SAFARI_ADDR_TO_P(value));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(buf, &lochdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf5(buf, PROC_FRU_PATH, SAFARI_ADDR_TO_SB(value),
03831d35f7499c87d51205817c93e9a8d42c4baestevel SAFARI_ADDR_TO_SB(value), SAFARI_ADDR_TO_P(value),
03831d35f7499c87d51205817c93e9a8d42c4baestevel SAFARI_ADDR_TO_P(value));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(buf, &fruhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(buf, "P%d", SAFARI_ADDR_TO_P(value));
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(fruhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_DEVICES, &tblhdl, sizeof (tblhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) create_cpu_references(buf, fruhdl, tblhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * subroutine for add_env_nodes(), and add_led_node(). Adds a sensor
03831d35f7499c87d51205817c93e9a8d42c4baestevel * node under the sc node in the platform tree, of name "nodename" and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * class "class". Also add UnitAddress property (always 0 as the nodenames
03831d35f7499c87d51205817c93e9a8d42c4baestevel * are unique anyway). Add reference property back to parent fru/location node
03831d35f7499c87d51205817c93e9a8d42c4baestevel * in frutree and a Devices table entry pointing to this node from the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * parent fru/location node in frutree.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_sensor_node(picl_nodehdl_t fruhdl, picl_nodehdl_t lochdl, char *nodename,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *class, char *prop_class, picl_prophdl_t tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *sensorhdlp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(sch, nodename, class, sensorhdlp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODE_FAIL, nodename, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, *sensorhdlp, class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_sensor_prop(*sensorhdlp, prop_class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(*sensorhdlp, "0", PICL_PROP_UNIT_ADDRESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fruhdl != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(*sensorhdlp, fruhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(*sensorhdlp, lochdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_REFPROP_LOC_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * subroutine for add_sensor_node()/add_env_nodes(). Used for adding dynamic
03831d35f7499c87d51205817c93e9a8d42c4baestevel * properties
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_sensor_prop(picl_nodehdl_t nodeh, char *class)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(class, PICL_PROP_TEMPERATURE) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_INT, PICL_READ + PICL_VOLATILE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (int), class, get_sensor_data, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(class, PICL_PROP_FAN_SPEED) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_INT, PICL_READ + PICL_VOLATILE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (int), class, get_sensor_data, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(class, PICL_PROP_FAN_SPEED_UNIT) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_CHARSTRING, PICL_READ + PICL_VOLATILE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_SPEED_UNIT_LEN, class, get_sensor_data, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(class, PICL_PROP_CONDITION) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_CHARSTRING, PICL_READ + PICL_VOLATILE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_CONDITION_LEN, class, get_sensor_data, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(class, PICL_PROP_STATE) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_CHARSTRING, PICL_READ + PICL_WRITE +
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_VOLATILE, MAX_STATE_LEN, class, get_led_data,
03831d35f7499c87d51205817c93e9a8d42c4baestevel set_led_data);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_FLOAT, PICL_READ + PICL_VOLATILE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (float), class, get_sensor_data, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL, class, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL, class, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get requested kstat
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelopen_kstat(char *name, void **ptr, kstat_ctl_t **kcp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_t *info_ksp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel *kcp = kstat_open();
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (*kcp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, KSTAT_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel info_ksp = kstat_lookup(*kcp, NULL, -1, name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (info_ksp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(*kcp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, KSTAT_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (kstat_read(*kcp, info_ksp, NULL) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(*kcp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, KSTAT_FAIL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel *ptr = info_ksp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dimm status - uses bank-status property on memory-controller node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_dimm_status(ptree_rarg_t *arg, void *result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t nextprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t refprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t mmgprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t mcprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t bankprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char nodename[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char class[PICL_CLASSNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char bankname[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char state[MAX_STATE_SIZE];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find the name of this node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_NAME, nodename,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (nodename));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_NAME, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find the name of grandparent (dimm bank) node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_PARENT, &bankprop,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(bankprop, PICL_PROP_PARENT, &bankprop,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(bankprop, PICL_PROP_NAME, bankname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (bankname));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_NAME, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * lookup memory-module node in Devices table
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_DEVICES, &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (tblhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_DEVICES, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_row(tblhdl, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if Devices table empty then dimm is unconfigured
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_DISABLED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_row(nextprop, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, GET_NEXT_BY_ROW_FAIL, PICL_PROP_DEVICES, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * walk down second column (ref ptr)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval(nextprop, &refprop, sizeof (refprop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, GET_PROPVAL_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(refprop, PICL_PROP_CLASSNAME,
03831d35f7499c87d51205817c93e9a8d42c4baestevel class, sizeof (class));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS && strcmp(class,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_MEMORY_MODULE) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS && err != PICL_STALEHANDLE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_CLASSNAME,
03831d35f7499c87d51205817c93e9a8d42c4baestevel err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_col(nextprop, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if no memory-module in Devices table
03831d35f7499c87d51205817c93e9a8d42c4baestevel * then dimm is unconfigured
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_DISABLED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we've finally found the associated memory-module
03831d35f7499c87d51205817c93e9a8d42c4baestevel * node. Now need to find the bank-status property on
03831d35f7499c87d51205817c93e9a8d42c4baestevel * its parent memory-controller.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(refprop, PICL_PROP_PARENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &mmgprop, sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(mmgprop, PICL_PROP_PARENT, &mcprop,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_PARENT, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(mcprop, PICL_PROP_BANK_STATUS, &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (tblhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_UNKNOWN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * bank-status is a table. Need to find the entry corresponding
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to this node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_row(tblhdl, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_UNKNOWN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < 4; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval(nextprop, &state, sizeof (state));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_UNKNOWN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((i & 1) == (bankname[1] - '0')) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(state, "pass") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_OKAY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(state, "fail") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_FAILED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, state,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_col(nextprop, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_OKAY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cpu status - uses State property on cpu node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_cpu_status(ptree_rarg_t *arg, void *result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t nextprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t refprop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char class[PICL_CLASSNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char state[MAX_STATE_SIZE];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * lookup cpu node in Devices table
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_DEVICES, &tblhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (tblhdl));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_DEVICES, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_row(tblhdl, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if Devices table empty then cpu is unconfigured
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_DISABLED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_row(nextprop, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, GET_NEXT_BY_ROW_FAIL, PICL_PROP_DEVICES, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * walk down second column (ref ptr)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval(nextprop, &refprop, sizeof (refprop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, GET_PROPVAL_FAIL, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(refprop, PICL_PROP_CLASSNAME,
03831d35f7499c87d51205817c93e9a8d42c4baestevel class, sizeof (class));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS && strcmp(class, PICL_CLASS_CPU) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS && err != PICL_STALEHANDLE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROP_LOOKUP_FAIL, PICL_PROP_CLASSNAME,
03831d35f7499c87d51205817c93e9a8d42c4baestevel err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_next_by_col(nextprop, &nextprop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if no cpu in Devices table
03831d35f7499c87d51205817c93e9a8d42c4baestevel * then cpu is unconfigured
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_DISABLED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we've finally found the associated cpu node. Now need to find its
03831d35f7499c87d51205817c93e9a8d42c4baestevel * status property if present (if not assume OK)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(refprop, OBP_STATUS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel state, sizeof (state));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(state, "fail") == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_FAILED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, state,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_OKAY, MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * system/io board condition - uses sgenv driver kstats
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_board_status(ptree_rarg_t *arg, void *result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = PICL_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sg_board_info_t *brd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_ctl_t *kc;
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_t *board_info_ksp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_NAME, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = open_kstat(SG_BOARD_STATUS_KSTAT_NAME, (void **)&board_info_ksp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel brd = board_info_ksp->ks_data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < SGENV_NUM_BOARD_READINGS(board_info_ksp); i++, brd++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check this kstat matches the name of the node
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (SG_BOARD_IS_CPU_TYPE(brd->board_num)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(buf, "%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_HPU_TYPE_CPU_BOARD_ID, brd->board_num);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(buf, "%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_HPU_TYPE_PCI_IO_BOARD_ID, brd->board_num);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strncmp(buf, name, strlen(buf)) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ok - got the right kstat - get it's value
03831d35f7499c87d51205817c93e9a8d42c4baestevel * note that values 0-4 are defined in sbdp_mbox.h
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (brd->condition >= 0 && brd->condition < 5)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_condition_table[brd->condition],
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_op_status(ptree_rarg_t *arg, void *result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = PICL_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char value[MAX_STATE_LEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char parent_name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t loch;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t parentfruh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_NAME, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * handle dimms, cpus and system boards specially
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_PROC_NODE(name)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (get_cpu_status(arg, result));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (IS_DIMM_NODE(name)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (get_dimm_status(arg, result));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (IS_SB_NODE(name) || IS_IB_NODE(name)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (get_board_status(arg, result));
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * otherwise OperationalStatus is derived from the fault led state
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * scapp knows FANs 0 and 1 on IB as FAN8 and FAN9
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_PARENT, &loch,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (loch));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(loch, PICL_PROP_PARENT, &parentfruh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (parentfruh));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(parentfruh, PICL_PROP_NAME, parent_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (parent_name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, "FAN0") == 0 && strcmp(parent_name, "IB6") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (get_led("FAN8", FAULT_LED, value) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(name, "FAN1") == 0 && strcmp(parent_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "IB6") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (get_led("FAN9", FAULT_LED, value) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (get_led(name, FAULT_LED, value) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(value, PICL_PROPVAL_ON) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_FAILED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_OKAY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_board_status(picl_nodehdl_t nodeh, char *nodename)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t prophdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check if OperationalStatus property already created for this fru
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(nodeh, PICL_PROP_OPERATIONAL_STATUS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &prophdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * put operational status on dimms, cpus, SBs, IBs, PSUs, FTs, Fans, RPs
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (IS_DIMM_NODE(nodename) || IS_PROC_NODE(nodename) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel IS_SB_NODE(nodename) || IS_IB_NODE(nodename) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel IS_PSU_NODE(nodename) || IS_FT_NODE(nodename) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel IS_FAN_NODE(nodename) || IS_RP_NODE(nodename)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PTYPE_CHARSTRING, PICL_READ + PICL_VOLATILE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_OPERATIONAL_STATUS_LEN, PICL_PROP_OPERATIONAL_STATUS,
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_op_status, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, PROPINFO_FAIL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_OPERATIONAL_STATUS, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_PROP_FAIL,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_OPERATIONAL_STATUS, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * environmental information handling - uses sgenv driver kstats
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_env_nodes(picl_nodehdl_t nodeh, char *nodename, picl_prophdl_t tblhdl)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = PICL_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel env_sensor_t *env;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t frutype;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char fruname[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char id[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel float scale;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t childh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t sensorhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_ctl_t *kc;
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_t *env_info_ksp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = open_kstat(SG_ENV_INFO_KSTAT_NAME, (void **)&env_info_ksp, &kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel env = env_info_ksp->ks_data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < SGENV_NUM_ENV_READINGS(env_info_ksp); i++, env++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check values from kstat entry are within valid range
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_type < SG_SENSOR_TYPE_CURRENT)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_type == SG_SENSOR_TYPE_ENVDB)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_type > SG_SENSOR_TYPE_2_5_VDC)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((env->sd_id.id.hpu_type >> 8) >=
03831d35f7499c87d51205817c93e9a8d42c4baestevel (SG_HPU_TYPE_SUN_FIRE_3800_CENTERPLANE >> 8))
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_part > SG_SENSOR_PART_INPUT)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * does this kstat entry belong to this fru?
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Note sc reports RPS as 10 and 12 via env messages
03831d35f7499c87d51205817c93e9a8d42c4baestevel * but by 0 and 2 via fru messages, so correct here
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((env->sd_id.id.hpu_type >> 8) ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel (SG_HPU_TYPE_REPEATER_BOARD >> 8)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(fruname, "%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_type_table[env->sd_id.id.hpu_type >> 8],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.hpu_slot - 10);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(fruname, "%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_type_table[env->sd_id.id.hpu_type >> 8],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.hpu_slot);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(nodename, fruname) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * set up FRUType. Note we only want to do this once per fru
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_prop_by_name(nodeh, PICL_PROP_FRU_TYPE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &frutype);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(nodeh,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_fru_type_table[env->sd_id.id.hpu_type >> 8],
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_FRU_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create the sensor node with a sensible name
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (env->sd_id.id.sensor_type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_TEMPERATURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_part == SG_SENSOR_PART_BOARD) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(id, "t_ambient%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_typenum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(id, "t_%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_CURRENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(id, "i_%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_COOLING:
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(id, "ft_%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default: /* voltage */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_part == SG_SENSOR_PART_BOARD) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(id, "v_%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_sensor_table[env->sd_id.id.sensor_type],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_typenum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(id, "v_%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check if sensor node has already been created
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(buf, "%s_%s", nodename, id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (find_child_by_name(sch, buf) != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_type == SG_SENSOR_TYPE_COOLING) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create individual fan_unit nodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel childh = nodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(fruname, "FAN%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&childh, fruname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &tblhdl2, "fan-unit", "FAN");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_board_status(childh, fruname);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (env->sd_id.id.sensor_part ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_SENSOR_PART_CHEETAH ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((env->sd_id.id.hpu_type >> 8) ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel (SG_HPU_TYPE_CPU_BOARD >> 8) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (env->sd_id.id.sensor_type == SG_SENSOR_TYPE_TEMPERATURE) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (env->sd_id.id.sensor_part == SG_SENSOR_PART_BOARD))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * put sensors under individual processor nodes
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel childh = nodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_part == SG_SENSOR_PART_BOARD)
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(fruname, "P%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_typenum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(fruname, "P%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_intermediate_nodes(&childh, fruname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &tblhdl2, "cpu", "PROC");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel childh = nodeh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel tblhdl2 = tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_sensor_node(childh, NULL, buf,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_sensor_class_table[env->sd_id.id.sensor_type],
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_sensor_prop_table[env->sd_id.id.sensor_type],
03831d35f7499c87d51205817c93e9a8d42c4baestevel tblhdl2, &sensorhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add additional properties
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (env->sd_id.id.sensor_type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_COOLING:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl, id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add threshold at 75% of full speed
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_int(sensorhdl, 75,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LOW_WARNING_THRESHOLD);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_sensor_prop(sensorhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_FAN_SPEED_UNIT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_TEMPERATURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((env->sd_id.id.hpu_type >> 8 ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel (SG_HPU_TYPE_CPU_BOARD >> 8)) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (env->sd_id.id.sensor_part ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_SENSOR_PART_BOARD)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_AMBIENT, PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (env->sd_id.id.sensor_part ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_SENSOR_PART_CHEETAH) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_DIE, PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl, id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_int(sensorhdl, env->sd_lo_warn /
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_TEMPERATURE_SCALE, PICL_PROP_LOW_WARNING);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_int(sensorhdl, env->sd_lo /
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_TEMPERATURE_SCALE, PICL_PROP_LOW_SHUTDOWN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_int(sensorhdl, env->sd_hi_warn /
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_TEMPERATURE_SCALE, PICL_PROP_HIGH_WARNING);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_int(sensorhdl, env->sd_hi /
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_TEMPERATURE_SCALE, PICL_PROP_HIGH_SHUTDOWN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_1_5_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel scale = SG_1_5_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_1_8_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel scale = SG_1_8_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_2_5_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel scale = SG_2_5_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_3_3_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel scale = SG_3_3_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_5_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel scale = SG_5_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_12_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel scale = SG_12_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_48_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The 48VDC sensor is just an indicator - doesn't
03831d35f7499c87d51205817c93e9a8d42c4baestevel * give reading or thresholds
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl, id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_CURRENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel scale = SG_CURRENT_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl, id, PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_float(sensorhdl, (float)env->sd_lo_warn / scale,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LOW_WARNING);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_float(sensorhdl, (float)env->sd_lo / scale,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LOW_SHUTDOWN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_float(sensorhdl, (float)env->sd_hi_warn / scale,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_HIGH_WARNING);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_float(sensorhdl, (float)env->sd_hi / scale,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_HIGH_SHUTDOWN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto done;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baesteveldone:
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_sensor_data(ptree_rarg_t *arg, void *result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err; /* return code */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_ctl_t *kc;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptree_propinfo_t propinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel env_sensor_t *env;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf1[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_t *env_info_ksp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_NAME, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_propinfo(arg->proph, &propinfo);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = open_kstat(SG_ENV_INFO_KSTAT_NAME, (void **)&env_info_ksp, &kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel env = env_info_ksp->ks_data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < SGENV_NUM_ENV_READINGS(env_info_ksp); i++, env++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check kstat values are within range
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (SG_INFO_VALUESTATUS(env->sd_infostamp) != SG_INFO_VALUE_OK)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_type < SG_SENSOR_TYPE_CURRENT)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_type == SG_SENSOR_TYPE_ENVDB)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_type > SG_SENSOR_TYPE_2_5_VDC)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((env->sd_id.id.hpu_type >> 8) >=
03831d35f7499c87d51205817c93e9a8d42c4baestevel (SG_HPU_TYPE_SUN_FIRE_3800_CENTERPLANE >> 8))
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_part > SG_SENSOR_PART_INPUT)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check this kstat matches the name of the node
03831d35f7499c87d51205817c93e9a8d42c4baestevel * note sc reports RPS as 10 and 12 via env messages
03831d35f7499c87d51205817c93e9a8d42c4baestevel * but by 0 and 2 via fru messages, so correct here
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((env->sd_id.id.hpu_type >> 8) ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel (SG_HPU_TYPE_REPEATER_BOARD >> 8))
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(buf, "%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_type_table[env->sd_id.id.hpu_type >> 8],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.hpu_slot - 10);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(buf, "%s%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_type_table[env->sd_id.id.hpu_type >> 8],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.hpu_slot);
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (env->sd_id.id.sensor_type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_TEMPERATURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_part == SG_SENSOR_PART_BOARD) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(buf1, "%s_t_ambient%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel buf, env->sd_id.id.sensor_typenum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(buf1, "%s_t_%s%d", buf,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_CURRENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(buf1, "%s_i_%s%d", buf,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_COOLING:
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(buf1, "%s_ft_%s%d", buf,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default: /* voltage */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (env->sd_id.id.sensor_part == SG_SENSOR_PART_BOARD) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(buf1, "%s_v_%s%d", buf,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_sensor_table[env->sd_id.id.sensor_type],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_typenum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf4(buf1, "%s_v_%s%d", buf,
03831d35f7499c87d51205817c93e9a8d42c4baestevel hpu_part_table[env->sd_id.id.sensor_part],
03831d35f7499c87d51205817c93e9a8d42c4baestevel env->sd_id.id.sensor_partnum);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(buf1, name) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ok - this is the kstat we want - update
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Condition, or sensor reading as requested
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(propinfo.piclinfo.name, PICL_PROP_CONDITION) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (SG_GET_SENSOR_STATUS(env->sd_status)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_OK:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_OKAY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_CONDITION_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_LO_WARN:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_HI_WARN:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_WARNING,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_CONDITION_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_LO_DANGER:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_HI_DANGER:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_FAILED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_CONDITION_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (env->sd_id.id.sensor_type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_TEMPERATURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(int *)result = env->sd_value / SG_TEMPERATURE_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_1_5_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(float *)result =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (float)env->sd_value / (float)SG_1_5_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_1_8_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(float *)result =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (float)env->sd_value / (float)SG_1_8_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_2_5_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(float *)result =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (float)env->sd_value / (float)SG_2_5_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_3_3_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(float *)result =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (float)env->sd_value / (float)SG_3_3_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_5_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(float *)result =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (float)env->sd_value / (float)SG_5_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_12_VDC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(float *)result =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (float)env->sd_value / (float)SG_12_VDC_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_CURRENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(float *)result =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (float)env->sd_value / (float)SG_CURRENT_SCALE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_TYPE_COOLING:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(propinfo.piclinfo.name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_FAN_SPEED_UNIT) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (SG_GET_SENSOR_STATUS(env->sd_status) ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel SG_SENSOR_STATUS_FAN_LOW) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_SELF_REGULATING,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_SPEED_UNIT_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_PER_CENT,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAX_SPEED_UNIT_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (SG_GET_SENSOR_STATUS(env->sd_status)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_FAN_HIGH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(int *)result = 100;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_FAN_FAIL:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_FAN_OFF:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(int *)result = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_SENSOR_STATUS_FAN_LOW:
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel kstat_close(kc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * led information handling - uses lw8 driver
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_led_nodes(picl_nodehdl_t nodeh, char *name, int position,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int ledfd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_get_led_t lom_get_led;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t sensorhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Open the lw8 pseudo dev to get the led information
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ledfd = open(LED_PSEUDO_DEV, O_RDWR, 0)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DEV_OPEN_FAIL, LED_PSEUDO_DEV, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero(&lom_get_led, sizeof (lom_get_led));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(lom_get_led.location, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lom_get_led.location));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(ledfd, LOMIOCGETLED, &lom_get_led) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, LED_IOCTL_FAIL, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (lom_get_led.next_id[0] != '\0') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(lom_get_led.id, lom_get_led.next_id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lom_get_led.id));
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_get_led.next_id[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_get_led.position = LOM_LED_POSITION_FRU;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(ledfd, LOMIOCGETLED, &lom_get_led) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, LED_IOCTL_FAIL, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf3(buf, "%s_%s", name, lom_get_led.id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (position != lom_get_led.position)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (position == LOM_LED_POSITION_LOCATION) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_sensor_node(NULL, nodeh, buf, PICL_CLASS_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_STATE, tblhdl, &sensorhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_sensor_node(nodeh, NULL, buf, PICL_CLASS_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_STATE, tblhdl, &sensorhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, "chassis") == 0 && strcmp(lom_get_led.id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "locator") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl, PICL_PROPVAL_TRUE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_IS_LOCATOR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_SYSTEM, PICL_PROP_LOCATOR_NAME);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl, lom_get_led.id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_LABEL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_charstring(sensorhdl, lom_get_led.color,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROP_COLOR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_led(char *name, char *ptr, char *result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int ledfd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_get_led_t lom_get_led;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Open the lw8 pseudo dev to get the led information
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ledfd = open(LED_PSEUDO_DEV, O_RDWR, 0)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DEV_OPEN_FAIL, LED_PSEUDO_DEV, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero(&lom_get_led, sizeof (lom_get_led));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(lom_get_led.location, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lom_get_led.location));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(lom_get_led.id, ptr, sizeof (lom_get_led.id));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(ledfd, LOMIOCGETLED, &lom_get_led) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, LED_IOCTL_FAIL, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (lom_get_led.status == LOM_LED_STATUS_ON)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_ON, MAX_STATE_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else if (lom_get_led.status == LOM_LED_STATUS_FLASHING)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_FLASHING, MAX_STATE_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else if (lom_get_led.status == LOM_LED_STATUS_BLINKING)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_BLINKING, MAX_STATE_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(result, PICL_PROPVAL_OFF, MAX_STATE_LEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_led_data(ptree_rarg_t *arg, void *result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rc; /* return code */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *ptr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rc = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_NAME, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rc != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptr = strchr(name, '_');
03831d35f7499c87d51205817c93e9a8d42c4baestevel *ptr++ = '\0'; /* now name is fru name, ptr is led name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (get_led(name, ptr, (char *)result));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelset_led(char *name, char *ptr, char *value)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int ledfd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_set_led_t lom_set_led;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Open the lw8 pseudo dev to set the led information
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ledfd = open(LED_PSEUDO_DEV, O_RDWR, 0)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DEV_OPEN_FAIL, LED_PSEUDO_DEV, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero(&lom_set_led, sizeof (lom_set_led));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(lom_set_led.location, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (lom_set_led.location));
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strlcpy(lom_set_led.id, ptr, sizeof (lom_set_led.id));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(value, PICL_PROPVAL_ON) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_set_led.status = LOM_LED_STATUS_ON;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(value, PICL_PROPVAL_FLASHING) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_set_led.status = LOM_LED_STATUS_FLASHING;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if (strcmp(value, PICL_PROPVAL_BLINKING) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_set_led.status = LOM_LED_STATUS_BLINKING;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lom_set_led.status = LOM_LED_STATUS_OFF;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(ledfd, LOMIOCSETLED, &lom_set_led) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, LED_IOCTL_FAIL, strerror(errno));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_PROPVALUNAVAILABLE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) close(ledfd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelset_led_data(ptree_warg_t *arg, const void *value)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rc; /* return code */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *ptr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rc = ptree_get_propval_by_name(arg->nodeh, PICL_PROP_NAME, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (name));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rc != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rc);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ptr = strchr(name, '_');
03831d35f7499c87d51205817c93e9a8d42c4baestevel *ptr++ = '\0'; /* now name is fru name, ptr is led name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (set_led(name, ptr, (char *)value));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisk_leds_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = 0, i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!g_mutex_init) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((pthread_cond_init(&g_cv, NULL) == 0) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pthread_cond_init(&g_cv_ack, NULL) == 0) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pthread_mutex_init(&g_mutex, NULL) == 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel g_mutex_init = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ledsthr_created) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * this is a restart, wake up sleeping threads
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = pthread_mutex_lock(&g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, EM_MUTEX_FAIL, strerror(err));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel g_wait_now = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_cond_broadcast(&g_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_mutex_unlock(&g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((pthread_attr_init(&ledsthr_attr) != 0) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pthread_attr_setscope(&ledsthr_attr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PTHREAD_SCOPE_SYSTEM) != 0))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((err = pthread_create(&ledsthr_tid, &ledsthr_attr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk_leds_thread, NULL)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, EM_THREAD_CREATE_FAILED, strerror(err));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel ledsthr_created = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < N_DISKS; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) set_led(lw8_disks[i].d_fruname, FAULT_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_OFF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisk_leds_fini(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * tell led thread to pause
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!ledsthr_created)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = pthread_mutex_lock(&g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, EM_MUTEX_FAIL, strerror(err));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel g_wait_now = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk_leds_thread_ack = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_cond_broadcast(&g_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and wait for the led thread to acknowledge
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (!disk_leds_thread_ack) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_cond_wait(&g_cv_ack, &g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_mutex_unlock(&g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelupdate_disk_node(struct lw8_disk *diskp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t slotndh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t diskndh;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t devhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tblhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char path[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *fruname = diskp->d_fruname;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf_buf2(path, CHASSIS_LOC_PATH, fruname);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ptree_get_node_by_path(path, &slotndh) != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel diskndh = find_child_by_name(slotndh, fruname);
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_get_node_by_path(diskp->d_plat_path, &devhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (diskndh != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_create_and_add_node(slotndh, fruname,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_CLASS_FRU, &diskndh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, ADD_NODE_FAIL, fruname, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table(diskndh, &tblhdl, PICL_PROP_DEVICES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = create_table_entry(tblhdl, devhdl, PICL_CLASS_BLOCK);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = add_prop_ref(devhdl, diskndh, PICL_REFPROP_FRU_PARENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (diskndh == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = ptree_delete_node(diskndh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) ptree_destroy_node(diskndh);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Implement a state machine in order to:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * o enable/disable disk LEDs
03831d35f7499c87d51205817c93e9a8d42c4baestevel * o add/delete the disk's node in the FRU tree
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The machine changes state based on the current, in-memory
03831d35f7499c87d51205817c93e9a8d42c4baestevel * state of the disk (eg, the d_state field of 'struct lw8_disk')
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and libdevice's current view of whether the disk is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Configured or Unconfigured.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the new state is the same as the previous state, then
03831d35f7499c87d51205817c93e9a8d42c4baestevel * no side effects occur. Otherwise, the LEDs for the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * disk are set and the disk's associated node in the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * FRU Tree is added or deleted.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelset_disk_leds(struct lw8_disk *disk)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel devctl_hdl_t dhdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t cur_state = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel dhdl = devctl_device_acquire(disk->d_devices_path, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (dhdl == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = errno;
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, DEVCTL_DEVICE_ACQUIRE_FAILED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel strerror(err));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel devctl_device_getstate(dhdl, &cur_state);
03831d35f7499c87d51205817c93e9a8d42c4baestevel devctl_release(dhdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((cur_state & DEVICE_OFFLINE) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (disk->d_state) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * State machine should never get here.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When NDEBUG is defined, control will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fall through and force d_state to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * match the semantics of "DEVICE_OFFLINE".
03831d35f7499c87d51205817c93e9a8d42c4baestevel * During development, NDEBUG can be undefined,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and this will fire an assertion.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel assert(0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*FALLTHROUGH*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DISK_STATE_NOT_INIT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DISK_STATE_READY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk->d_state = DISK_STATE_NOT_READY;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) set_led(disk->d_fruname, POWER_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_OFF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) set_led(disk->d_fruname, REMOK_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_ON);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel update_disk_node(disk);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DISK_STATE_NOT_READY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if ((cur_state & DEVICE_ONLINE) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (disk->d_state) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * State machine should never get here.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When NDEBUG is defined, control will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fall through and force d_state to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * match the semantics of "DEVICE_ONLINE".
03831d35f7499c87d51205817c93e9a8d42c4baestevel * During development, NDEBUG can be undefined,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and this will fire an assertion.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel assert(0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*FALLTHROUGH*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DISK_STATE_NOT_INIT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DISK_STATE_NOT_READY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk->d_state = DISK_STATE_READY;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) set_led(disk->d_fruname, REMOK_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_OFF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) set_led(disk->d_fruname, POWER_LED,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPVAL_ON);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel update_disk_node(disk);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DISK_STATE_READY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * NOTE: this implementation of disk_leds_thread is based on the version in
03831d35f7499c87d51205817c93e9a8d42c4baestevel * plugins/sun4u/mpxu/frudr/piclfrudr.c (with V440 raid support removed). Some
03831d35f7499c87d51205817c93e9a8d42c4baestevel * day the source code layout and build environment should support common code
03831d35f7499c87d51205817c93e9a8d42c4baestevel * used by platform specific plugins, in which case LW8 support could be added
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to the mpxu version (which would be moved to a common directory).
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void *
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisk_leds_thread(void *args)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int n_disks = N_DISKS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel static char *lw8_pci_devs[] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DISK0_BASE_PATH,
03831d35f7499c87d51205817c93e9a8d42c4baestevel DISK1_BASE_PATH
03831d35f7499c87d51205817c93e9a8d42c4baestevel };
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel static char *lw8_pcix_devs[] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DISK0_BASE_PATH_PCIX,
03831d35f7499c87d51205817c93e9a8d42c4baestevel DISK1_BASE_PATH_PCIX
03831d35f7499c87d51205817c93e9a8d42c4baestevel };
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel static char **lw8_devs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pcix_io) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_devs = lw8_pcix_devs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_devs = lw8_pci_devs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create aliases for disk names
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < n_disks; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buffer[MAXPATHLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buffer, sizeof (buffer), "/devices%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_devs[i]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_disks[i].d_devices_path = strdup(buffer);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buffer, sizeof (buffer), "/platform%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_devs[i]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel lw8_disks[i].d_plat_path = strdup(buffer);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (;;) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < n_disks; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel set_disk_leds(&lw8_disks[i]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * wait a bit until we check again
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = poll(NULL, 0, ledsthr_poll_period);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = errno;
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, EM_POLL_FAIL, strerror(err));
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = pthread_mutex_lock(&g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel syslog(LOG_ERR, EM_MUTEX_FAIL, strerror(err));
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (g_wait_now != B_FALSE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* notify _fini routine that we've paused */
03831d35f7499c87d51205817c93e9a8d42c4baestevel disk_leds_thread_ack = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_cond_signal(&g_cv_ack);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* and go to sleep in case we get restarted */
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (g_wait_now != B_FALSE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_cond_wait(&g_cv, &g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) pthread_mutex_unlock(&g_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return ((void *)err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}