29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER START
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * The contents of this file are subject to the terms of the
29949e866e40b95795203f3ee46f44a197c946e4stevel * Common Development and Distribution License (the "License").
29949e866e40b95795203f3ee46f44a197c946e4stevel * You may not use this file except in compliance with the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
29949e866e40b95795203f3ee46f44a197c946e4stevel * or http://www.opensolaris.org/os/licensing.
29949e866e40b95795203f3ee46f44a197c946e4stevel * See the License for the specific language governing permissions
29949e866e40b95795203f3ee46f44a197c946e4stevel * and limitations under the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * When distributing Covered Code, include this CDDL HEADER in each
29949e866e40b95795203f3ee46f44a197c946e4stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
29949e866e40b95795203f3ee46f44a197c946e4stevel * If applicable, add the following below this CDDL HEADER, with the
29949e866e40b95795203f3ee46f44a197c946e4stevel * fields enclosed by brackets "[]" replaced with your own identifying
29949e866e40b95795203f3ee46f44a197c946e4stevel * information: Portions Copyright [yyyy] [name of copyright owner]
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER END
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Use is subject to license terms.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#pragma ident "%Z%%M% %I% %E% SMI"
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/types.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/conf.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/ddi.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sunddi.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sunndi.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/ddi_impldefs.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/ndi_impldefs.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/obpdefs.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/cmn_err.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/errno.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/kmem.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/debug.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sysmacros.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/ivintr.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/autoconf.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/intreg.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/proc.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/machsystm.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/modctl.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/callb.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/file.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/open.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/stat.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/fhc.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sysctrl.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/jtag.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/ac.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/simmstat.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/clock.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/promif.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/promimpl.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/cpr.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/cpuvar.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/machcpuvar.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/x_call.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevelstruct regs_data {
29949e866e40b95795203f3ee46f44a197c946e4stevel caddr_t msg;
29949e866e40b95795203f3ee46f44a197c946e4stevel u_longlong_t physaddr;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t pre_dsct;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t post_dsct;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t eflag;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t oflag;
29949e866e40b95795203f3ee46f44a197c946e4stevel};
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic struct regs_data reg_tmpl[] = {
29949e866e40b95795203f3ee46f44a197c946e4stevel "AC Control and Status reg = 0x", AC_BCSR(0), 0, 0, 0, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "FHC Control and Status reg = 0x", FHC_CTRL(0), 0, 0, 0, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "JTAG Control reg = 0x", FHC_JTAG_CTRL(0), 0, 0, 0, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "Interrupt Group Number reg = 0x", FHC_IGN(0), 0, 0, 0, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "System Interrupt Mapping reg = 0x", FHC_SIM(0), 0, 0, 0, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "System Interrupt State reg = 0x", FHC_SSM(0), 0, 0, 0, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "UART Interrupt Mapping reg = 0x", FHC_UIM(0), 0, 0, 0, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "UART Interrupt State reg = 0x", FHC_USM(0), 0, 0, 0, 0
29949e866e40b95795203f3ee46f44a197c946e4stevel};
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#define NUM_REG (sizeof (reg_tmpl)/sizeof (reg_tmpl[0]))
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic struct regs_data reg_dt[MAX_BOARDS][NUM_REG];
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint sysctrl_enable_regdump = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void precache_regdump(int board);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void display_regdump(void);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void boardstat_regdump(void);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* DEBUG */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelextern void bd_remove_poll(struct sysctrl_soft_state *);
29949e866e40b95795203f3ee46f44a197c946e4stevelextern int sysctrl_getsystem_freq(void);
29949e866e40b95795203f3ee46f44a197c946e4stevelextern enum power_state compute_power_state(struct sysctrl_soft_state *, int);
29949e866e40b95795203f3ee46f44a197c946e4stevelextern enum temp_state fhc_env_temp_state(int);
29949e866e40b95795203f3ee46f44a197c946e4stevelextern int sysctrl_hotplug_disabled;
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Let user disable Sunfire Dynamic Reconfiguration */
29949e866e40b95795203f3ee46f44a197c946e4stevelint enable_dynamic_reconfiguration = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint enable_redist = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_dr_err_decode(sysc_dr_handle_t *, dev_info_t *, int);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_enough_cooling(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, uint_t ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_enough_precharge(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_enough_power(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel int plus_load, uint_t ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_hardware_compatible(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, sysc_cfga_pkt_t *pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_policy_empty_condition(
29949e866e40b95795203f3ee46f44a197c946e4stevel struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, uint_t failure,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_policy_disconnected_condition(
29949e866e40b95795203f3ee46f44a197c946e4stevel struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, uint_t failure,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_policy_connected_condition(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_policy_set_condition(void *sp, sysc_cfga_stat_t *sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_policy_audit_messages(sysc_audit_evt_t event,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysctrl_post_config_change(struct sysctrl_soft_state *softsp);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_bd_connect(int, sysc_cfga_pkt_t *);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_bd_disconnect(int, sysc_cfga_pkt_t *);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_bd_configure(int, sysc_cfga_pkt_t *);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_bd_unconfigure(int, sysc_cfga_pkt_t *);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_dr_init(sysc_dr_handle_t *handle);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_dr_uninit(sysc_dr_handle_t *handle);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_dr_attach(sysc_dr_handle_t *handle, int board);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_dr_detach(sysc_dr_handle_t *handle, int board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_prom_select(pnode_t pnode, void *arg, uint_t flag);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void sysc_branch_callback(dev_info_t *rdip, void *arg, uint_t flags);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int find_and_setup_cpu(int);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int sysc_board_connect_supported(enum board_type);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int find_and_setup_cpu_start(void *cpuid_arg, int has_changed);
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function will basically do a prediction on the power state
29949e866e40b95795203f3ee46f44a197c946e4stevel * based on adding one additional load to the equation implemented
29949e866e40b95795203f3ee46f44a197c946e4stevel * by the function compute_power_state.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_enough_power(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel int plus_load, uint_t ps_mutex_is_held)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(softsp);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!ps_mutex_is_held) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&softsp->ps_fail_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * note that we add one more load
29949e866e40b95795203f3ee46f44a197c946e4stevel * to the equation in compute_power_state
29949e866e40b95795203f3ee46f44a197c946e4stevel * and the answer better be REDUNDANT or
29949e866e40b95795203f3ee46f44a197c946e4stevel * MINIMUM before proceeding.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (compute_power_state(softsp, plus_load)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case REDUNDANT:
29949e866e40b95795203f3ee46f44a197c946e4stevel case MINIMUM:
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case BELOW_MINIMUM:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!ps_mutex_is_held) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&softsp->ps_fail_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (retval);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function gropes through the shadow registers in the sysctrl soft_state
29949e866e40b95795203f3ee46f44a197c946e4stevel * for the core power supply status, since fan status for them are ORed into
29949e866e40b95795203f3ee46f44a197c946e4stevel * the same status bit, and all other remaining fans.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_enough_cooling(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, uint_t ps_mutex_is_held)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!ps_mutex_is_held) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&softsp->ps_fail_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * check the power supply in the slot in question
29949e866e40b95795203f3ee46f44a197c946e4stevel * for fans then check all the common fans.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = ((softsp->ps_stats[FHC_BOARD2PS(sysc_stat->board)].pshadow ==
29949e866e40b95795203f3ee46f44a197c946e4stevel PRES_IN) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel (softsp->ps_stats[FHC_BOARD2PS(sysc_stat->board)].dcshadow ==
29949e866e40b95795203f3ee46f44a197c946e4stevel PS_OK));
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!ps_mutex_is_held) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&softsp->ps_fail_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (retval);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function will check all precharge voltage status.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_enough_precharge(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel int ppsval = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&softsp->ps_fail_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * note that we always have to explicitly check
29949e866e40b95795203f3ee46f44a197c946e4stevel * the peripheral power supply for precharge since it
29949e866e40b95795203f3ee46f44a197c946e4stevel * supplies all of the precharge voltages.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel ppsval = (softsp->ps_stats[SYS_PPS0_INDEX].pshadow == PRES_IN) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel (softsp->ps_stats[SYS_PPS0_INDEX].dcshadow == PS_OK);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * check all the precharge status
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = ((softsp->ps_stats[SYS_V3_PCH_INDEX].pshadow == PRES_IN) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel (softsp->ps_stats[SYS_V3_PCH_INDEX].dcshadow == PS_OK) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel (softsp->ps_stats[SYS_V5_PCH_INDEX].pshadow == PRES_IN) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel (softsp->ps_stats[SYS_V5_PCH_INDEX].dcshadow == PS_OK));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&softsp->ps_fail_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (retval&&ppsval);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int Fsys;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function should only be called once as we may
29949e866e40b95795203f3ee46f44a197c946e4stevel * zero the clock board registers to indicate a configuration change.
29949e866e40b95795203f3ee46f44a197c946e4stevel * The code to calculate the bus frequency has been removed and we
29949e866e40b95795203f3ee46f44a197c946e4stevel * read the eeprom property instead. Another static Fmod (module
29949e866e40b95795203f3ee46f44a197c946e4stevel * frequency may be needed later but so far it is commented out.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelset_clockbrd_info(void)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t clock_freq = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel pnode_t root = prom_nextnode((pnode_t)0);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) prom_getprop(root, "clock-frequency", (caddr_t)&clock_freq);
29949e866e40b95795203f3ee46f44a197c946e4stevel Fsys = clock_freq / 1000000;
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#define abs(x) ((x) < 0 ? -(x) : (x))
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic uint_t
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_hardware_compatible(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, sysc_cfga_pkt_t *pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int status;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(Fsys > 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Only allow DR operations on supported hardware */
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->type) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case CPU_BOARD: {
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef RFE_4174486
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel int cpu_freq;
29949e866e40b95795203f3ee46f44a197c946e4stevel int sram_mode;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(Fmod > 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_freq = CPU->cpu_type_info.pi_clock;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (abs(cpu_freq - Fmod) < 8)
29949e866e40b95795203f3ee46f44a197c946e4stevel sram_mode = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel sram_mode = 2;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel status = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0; i < 2; i++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * XXX: Add jtag code which rescans disabled boards.
29949e866e40b95795203f3ee46f44a197c946e4stevel * For the time being disabled boards are not
29949e866e40b95795203f3ee46f44a197c946e4stevel * checked for compatibility when cpu_speed is 0.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_stat->bd.cpu[i].cpu_speed == 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_stat->bd.cpu[i].cpu_speed < cpu_freq) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "board %d, cpu module %c "
29949e866e40b95795203f3ee46f44a197c946e4stevel "rated at %d Mhz, system freq %d Mhz",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board, (i == 0) ? 'A' : 'B',
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->bd.cpu[i].cpu_speed,
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_freq);
29949e866e40b95795203f3ee46f44a197c946e4stevel status = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sram_mode != sysc_stat->bd.cpu[i].cpu_sram_mode) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "board %d, cpu module %c "
29949e866e40b95795203f3ee46f44a197c946e4stevel "incompatible sram mode of %dx, "
29949e866e40b95795203f3ee46f44a197c946e4stevel "system is %dx", sysc_stat->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel (i == 0) ? 'A' : 'B',
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->bd.cpu[i].cpu_sram_mode,
29949e866e40b95795203f3ee46f44a197c946e4stevel sram_mode);
29949e866e40b95795203f3ee46f44a197c946e4stevel status = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* RFE_4174486 */
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case MEM_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_2SBUS_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_SBUS_FFB_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_PCI_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_2SBUS_SOCPLUS_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_SBUS_FFB_SOCPLUS_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel status = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case CLOCK_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel case DISK_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel status = FALSE; /* default is not supported */
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (status == FALSE)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (status);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Check for Sunfire boards in a Sunfire+ system */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (status == TRUE && Fsys > 84 && !fhc_bd_is_plus(sysc_stat->board)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(pkt->errbuf, SYSC_OUTPUT_LEN,
29949e866e40b95795203f3ee46f44a197c946e4stevel "not 100 MHz capable ");
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "board %d, is not capable of running at "
29949e866e40b95795203f3ee46f44a197c946e4stevel "current system clock (%dMhz)", sysc_stat->board, Fsys);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel status = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (status);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function is called to check the policy for a request to transition
29949e866e40b95795203f3ee46f44a197c946e4stevel * to the connected state from the disconnected state. The generic policy
29949e866e40b95795203f3ee46f44a197c946e4stevel * is to do sanity checks again before going live.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_connect(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_pkt_t *pkt, sysc_cfga_stat_t *sysc_stat)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->rstate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_DISCONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Safety policy: only allow connect if board is UNKNOWN cond.
29949e866e40b95795203f3ee46f44a197c946e4stevel * cold start board will be demoted to UNKNOWN cond when
29949e866e40b95795203f3ee46f44a197c946e4stevel * disconnected
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_stat->condition != SYSC_CFGA_COND_UNKNOWN) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_COND);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EINVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!enable_dynamic_reconfiguration) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_NON_DR_PROM);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysctrl_hotplug_disabled) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_HOTPLUG);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Check PROM support. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_board_connect_supported(sysc_stat->type)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "%s board %d connect"
29949e866e40b95795203f3ee46f44a197c946e4stevel " is not supported by firmware.",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type), sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_HW_COMPAT);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_policy_enough_power(softsp, TRUE, FALSE)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_POWER);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EAGAIN);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_policy_enough_precharge(softsp, sysc_stat)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_PRECHARGE);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EAGAIN);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_policy_enough_cooling(softsp, sysc_stat, FALSE)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_COOLING);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EAGAIN);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_policy_hardware_compatible(softsp, sysc_stat, pkt)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_HW_COMPAT);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(SYSC_AUDIT_RSTATE_CONNECT,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = sysc_bd_connect(sysc_stat->board, pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!retval) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_CONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_connected_condition(softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(SYSC_AUDIT_RSTATE_SUCCEEDED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t prom_failure;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_failure = (retval == EIO &&
29949e866e40b95795203f3ee46f44a197c946e4stevel pkt->cmd_cfga.errtype == SYSC_ERR_PROM) ?
29949e866e40b95795203f3ee46f44a197c946e4stevel TRUE : FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_disconnected_condition(softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, prom_failure, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_AUDIT_RSTATE_CONNECT_FAILED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_CONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_RSTATE);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = EINVAL;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current Condition: %d\n", sysc_stat->condition));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (retval);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function is called to check the policy for a request to transition
29949e866e40b95795203f3ee46f44a197c946e4stevel * to the disconnected state from the connected/unconfigured state only.
29949e866e40b95795203f3ee46f44a197c946e4stevel * All other requests are invalid.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_disconnect(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_pkt_t *pkt, sysc_cfga_stat_t *sysc_stat)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->rstate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_CONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->ostate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_UNCONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!enable_dynamic_reconfiguration) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_NON_DR_PROM);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Check PROM support. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_board_connect_supported(sysc_stat->type)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "%s board %d disconnect"
29949e866e40b95795203f3ee46f44a197c946e4stevel " is not supported by firmware.",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_HW_COMPAT);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_policy_hardware_compatible(softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, pkt)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "%s board %d disconnect"
29949e866e40b95795203f3ee46f44a197c946e4stevel " is not yet supported.",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_HW_COMPAT);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (fhc_bd_is_jtag_master(sysc_stat->board)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_update(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_EVT_BD_CORE_RESOURCE_DISCONNECT);
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_CORE_RESOURCE);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EINVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(SYSC_AUDIT_RSTATE_DISCONNECT,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = sysc_bd_disconnect(sysc_stat->board, pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!retval) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate =
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_RSTATE_DISCONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSCTRL_ATTACH_DEBUG,
29949e866e40b95795203f3ee46f44a197c946e4stevel ("disconnect starting bd_remove_poll()"));
29949e866e40b95795203f3ee46f44a197c946e4stevel bd_remove_poll(softsp);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_disconnected_condition(
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, FALSE, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_AUDIT_RSTATE_SUCCEEDED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "board %d is ready to remove",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_connected_condition(
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp, sysc_stat, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_AUDIT_RSTATE_DISCONNECT_FAILED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_CONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_OSTATE);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = EINVAL;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_DISCONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_RSTATE);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = EINVAL;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current Condition: %d\n", sysc_stat->condition));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (retval);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function is called to check the policy for a request to transition
29949e866e40b95795203f3ee46f44a197c946e4stevel * from the connected/configured state to the connected/unconfigured state only.
29949e866e40b95795203f3ee46f44a197c946e4stevel * All other requests are invalid.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_unconfigure(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_pkt_t *pkt, sysc_cfga_stat_t *sysc_stat)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->ostate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_CONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!enable_dynamic_reconfiguration) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_NON_DR_PROM);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sysc_policy_hardware_compatible(softsp, sysc_stat, pkt)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "%s board %d unconfigure"
29949e866e40b95795203f3ee46f44a197c946e4stevel " is not yet supported.",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type), sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_HW_COMPAT);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENOTSUP);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(SYSC_AUDIT_OSTATE_UNCONFIGURE,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = sysc_bd_unconfigure(sysc_stat->board, pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!retval) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_AUDIT_OSTATE_SUCCEEDED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_AUDIT_OSTATE_UNCONFIGURE_FAILED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_connected_condition(softsp, sysc_stat, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_UNCONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_OSTATE);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = EINVAL;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current Condition: %d\n", sysc_stat->condition));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (retval);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function is called to check the policy for a requested transition
29949e866e40b95795203f3ee46f44a197c946e4stevel * from either the connected/unconfigured state or the connected/configured
29949e866e40b95795203f3ee46f44a197c946e4stevel * state to the connected/configured state. The redundant state transition
29949e866e40b95795203f3ee46f44a197c946e4stevel * is permitted for partially configured set of devices. Basically, we
29949e866e40b95795203f3ee46f44a197c946e4stevel * retry the configure.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_configure(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_pkt_t *pkt, sysc_cfga_stat_t *sysc_stat)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Previous OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->rstate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_CONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->ostate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_UNCONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_stat->condition != SYSC_CFGA_COND_OK) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_COND);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EINVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(SYSC_AUDIT_OSTATE_CONFIGURE,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = sysc_bd_configure(sysc_stat->board, pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_CONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_connected_condition(softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!retval) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_AUDIT_OSTATE_SUCCEEDED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_audit_messages(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_AUDIT_OSTATE_CONFIGURE_FAILED,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_CONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_OSTATE);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = ENOTSUP;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_OSTATE);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = EINVAL;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_DISCONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_RSTATE);
29949e866e40b95795203f3ee46f44a197c946e4stevel retval = EINVAL;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current RState: %d\n", sysc_stat->rstate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current OState: %d\n", sysc_stat->ostate));
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("Current Condition: %d\n", sysc_stat->condition));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (retval);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_empty_condition(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, uint_t failure,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->condition) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNKNOWN:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_OK:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILING:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel /* nothing in the slot so just check power supplies */
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNUSABLE:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_policy_enough_cooling(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel ps_mutex_is_held) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_enough_power(softsp, FALSE,
29949e866e40b95795203f3ee46f44a197c946e4stevel ps_mutex_is_held)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNKNOWN;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNUSABLE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->last_change = gethrestime_sec();
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_disconnected_condition(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat, uint_t failure,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (failure) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_FAILED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->last_change = gethrestime_sec();
29949e866e40b95795203f3ee46f44a197c946e4stevel return;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->condition) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * if unknown, we have come from hotplug case so do a quick
29949e866e40b95795203f3ee46f44a197c946e4stevel * reevaluation.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNKNOWN:
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * if ok, we have come from connected to disconnected and we stay
29949e866e40b95795203f3ee46f44a197c946e4stevel * ok until removed or reevaluate when reconnect. We might have
29949e866e40b95795203f3ee46f44a197c946e4stevel * experienced a ps fail so reevaluate the condition.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_OK:
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * if unsuable, either power supply was missing or
29949e866e40b95795203f3ee46f44a197c946e4stevel * hardware was not compatible. Check to see if
29949e866e40b95795203f3ee46f44a197c946e4stevel * this is still true.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNUSABLE:
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * failing must transition in the disconnected state
29949e866e40b95795203f3ee46f44a197c946e4stevel * to either unusable or unknown. We may have come here
29949e866e40b95795203f3ee46f44a197c946e4stevel * from cfgadm -f -c disconnect after a power supply failure
29949e866e40b95795203f3ee46f44a197c946e4stevel * in an attempt to protect the board.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILING:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_policy_enough_cooling(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel ps_mutex_is_held) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_enough_power(softsp, FALSE,
29949e866e40b95795203f3ee46f44a197c946e4stevel ps_mutex_is_held)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNKNOWN;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNUSABLE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->last_change = gethrestime_sec();
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * if failed, we have failed POST and must stay in this
29949e866e40b95795203f3ee46f44a197c946e4stevel * condition until the board has been removed
29949e866e40b95795203f3ee46f44a197c946e4stevel * before ever coming back into another condition
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_connected_condition(struct sysctrl_soft_state *softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->condition) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNKNOWN:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_OK:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILING:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNUSABLE:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_policy_enough_cooling(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel ps_mutex_is_held) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_enough_power(softsp, FALSE,
29949e866e40b95795203f3ee46f44a197c946e4stevel ps_mutex_is_held) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel (fhc_env_temp_state(sysc_stat->board) == TEMP_OK)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_OK;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_FAILING;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->last_change = gethrestime_sec();
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_set_condition(void *sp, sysc_cfga_stat_t *sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t ps_mutex_is_held)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct sysctrl_soft_state *softsp = (struct sysctrl_soft_state *)sp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sysc_stat->rstate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_empty_condition(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel FALSE, ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_DISCONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_disconnected_condition(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel FALSE, ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_CONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_connected_condition(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel ps_mutex_is_held);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_update(void *softsp, sysc_cfga_stat_t *sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_evt_t event)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *list;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(event == SYSC_EVT_BD_HP_DISABLED || fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (event) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_EMPTY;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNKNOWN;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_empty_condition(softsp, sysc_stat, FALSE, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_PRESENT:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_stat->type == DISK_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNKNOWN;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_CONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_CONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_OK;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->last_change = gethrestime_sec();
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_DISABLED:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNKNOWN;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_disconnected_condition(softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, FALSE, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "disabled %s board in slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNUSABLE;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_disconnected_condition(softsp, sysc_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel TRUE, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN,
29949e866e40b95795203f3ee46f44a197c946e4stevel "failed %s board in slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_OVERTEMP:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_TEMP_OK:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_set_condition((void *)softsp, sysc_stat, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_PS_CHANGE:
29949e866e40b95795203f3ee46f44a197c946e4stevel for (list = fhc_bd_first(); list; list = fhc_bd_next(list)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat = &(list->sc);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_set_condition((void *)softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_INS_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "powerdown of board %d failed",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_INSERTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysctrl_post_config_change(softsp);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_disconnected_condition(softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, FALSE, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "%s board has been inserted into slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type), sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "board %d can be removed", sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_REMOVED:
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->rstate = SYSC_CFGA_RSTATE_EMPTY;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->condition = SYSC_CFGA_COND_UNKNOWN;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* now it is ok to free the ac pa memory database */
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_del_memloc(sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* reinitialize sysc_cfga_stat structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->type = UNKNOWN_BOARD;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->fhc_compid = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->ac_compid = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) bzero(&(sysc_stat->prom_rev),
29949e866e40b95795203f3ee46f44a197c946e4stevel sizeof (sysc_stat->prom_rev));
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) bzero(&(sysc_stat->bd),
29949e866e40b95795203f3ee46f44a197c946e4stevel sizeof (union bd_un));
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->no_detach = sysc_stat->plus_board = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_policy_disconnected_condition(softsp,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat, FALSE, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "board %d has been removed",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_HP_DISABLED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "Hot Plug not supported in this system");
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_EVT_BD_CORE_RESOURCE_DISCONNECT:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "board %d cannot be disconnected because it"
29949e866e40b95795203f3ee46f44a197c946e4stevel " is a core system resource", sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * signal to POST that the system has been reconfigured and that
29949e866e40b95795203f3ee46f44a197c946e4stevel * the system configuration status information should be invalidated
29949e866e40b95795203f3ee46f44a197c946e4stevel * the next time through POST
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysctrl_post_config_change(struct sysctrl_soft_state *softsp)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * We are heading into a configuration change!
29949e866e40b95795203f3ee46f44a197c946e4stevel * Tell post to invalidate its notion of the system configuration.
29949e866e40b95795203f3ee46f44a197c946e4stevel * This is done by clearing the clock registers...
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel *softsp->clk_freq1 = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel *softsp->clk_freq2 &=
29949e866e40b95795203f3ee46f44a197c946e4stevel ~(CLOCK_FREQ_8 | CLOCK_DIV_1 | CLOCK_RANGE | CLOCK_DIV_0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_attach_board(void *arg)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int board = *(int *)arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (prom_sunfire_attach_board((uint_t)board));
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_bd_connect(int board, sysc_cfga_pkt_t *pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int error = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_handle_t *sh;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint64_t mempa;
29949e866e40b95795203f3ee46f44a197c946e4stevel int del_kstat = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_busy(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* find gap for largest supported simm in advance */
29949e866e40b95795203f3ee46f44a197c946e4stevel#define MAX_BANK_SIZE_MB (2 * 1024)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define BANKS_PER_BOARD 2
29949e866e40b95795203f3ee46f44a197c946e4stevel mempa = fhc_find_memloc_gap(BANKS_PER_BOARD * MAX_BANK_SIZE_MB);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* TODO: Is mempa vulnerable to re-use here? */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysctrl_suspend_prepare();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((error = sysctrl_suspend(pkt)) == DDI_SUCCESS) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* ASSERT(jtag not held) */
29949e866e40b95795203f3ee46f44a197c946e4stevel error = prom_tree_update(sysc_attach_board, &board);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel error = EIO;
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_PROM);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* attempt to program the memory while frozen */
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_program_memory(board, mempa);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sysctrl_resume(pkt);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel goto done;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Must not delete kstat used by prtdiag until the PROM
29949e866e40b95795203f3ee46f44a197c946e4stevel * has successfully connected to board.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel del_kstat = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sh = &bdp->sh[SYSC_DR_HANDLE_FHC];
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->flags |= SYSC_DR_FHC;
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->errstr = pkt->errbuf;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_init(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel error = sysc_dr_attach(sh, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error)
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_NDI_ATTACH);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_uninit(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (enable_redist) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel intr_redist_all_cpus();
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4steveldone:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (del_kstat && bdp->ksp) {
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_delete(bdp->ksp);
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->ksp = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (error);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_detach_board(void * arg)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int rt;
29949e866e40b95795203f3ee46f44a197c946e4stevel cpuset_t xcset;
29949e866e40b95795203f3ee46f44a197c946e4stevel struct jt_mstr *jtm;
29949e866e40b95795203f3ee46f44a197c946e4stevel int board = *(int *)arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevel /* it is important to have fhc_bdlist_lock() earlier */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysctrl_enable_regdump)
29949e866e40b95795203f3ee46f44a197c946e4stevel precache_regdump(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* DEBUG */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel jtm = jtag_master_lock();
29949e866e40b95795203f3ee46f44a197c946e4stevel CPUSET_ALL(xcset);
29949e866e40b95795203f3ee46f44a197c946e4stevel promsafe_xc_attention(xcset);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysctrl_enable_regdump)
29949e866e40b95795203f3ee46f44a197c946e4stevel boardstat_regdump();
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* DEBUG */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel rt = prom_sunfire_detach_board((uint_t)board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysctrl_enable_regdump)
29949e866e40b95795203f3ee46f44a197c946e4stevel display_regdump();
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* DEBUG */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel xc_dismissed(xcset);
29949e866e40b95795203f3ee46f44a197c946e4stevel jtag_master_unlock(jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel return (rt);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_bd_disconnect(int board, sysc_cfga_pkt_t *pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int error;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_handle_t *sh;
29949e866e40b95795203f3ee46f44a197c946e4stevel void fhc_bd_ks_alloc(fhc_bd_t *);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_busy(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(!fhc_bd_is_jtag_master(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->flags |= BDF_DETACH;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sh = &bdp->sh[SYSC_DR_HANDLE_FHC];
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->errstr = pkt->errbuf;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(sh->dip_list == NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->flags |= SYSC_DR_FHC;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_init(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel error = sysc_dr_detach(sh, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->flags &= ~SYSC_DR_REMOVE;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_uninit(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_NDI_DETACH);
29949e866e40b95795203f3ee46f44a197c946e4stevel goto done;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel error = prom_tree_update(sysc_detach_board, &board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel error = EIO;
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_PROM);
29949e866e40b95795203f3ee46f44a197c946e4stevel goto done;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (enable_redist) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel intr_redist_all_cpus();
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_ks_alloc(bdp);
29949e866e40b95795203f3ee46f44a197c946e4steveldone:
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (error);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_bd_configure(int board, sysc_cfga_pkt_t *pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int error = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_handle_t *sh;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_busy(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sh = &bdp->sh[SYSC_DR_HANDLE_DEVS];
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->errstr = pkt->errbuf;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(sh->dip_list == NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_init(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->flags |= SYSC_DR_DEVS;
29949e866e40b95795203f3ee46f44a197c946e4stevel error = sysc_dr_attach(sh, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_NDI_ATTACH);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_uninit(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel goto done;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_uninit(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (enable_redist) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel intr_redist_all_cpus();
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4steveldone:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->sc.type == CPU_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Value of error gets lost for CPU boards.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel error = find_and_setup_cpu(FHC_BOARD2CPU_A(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((error == 0) || (error == ENODEV)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel int retval_b;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel retval_b = find_and_setup_cpu(FHC_BOARD2CPU_B(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel if (retval_b != ENODEV)
29949e866e40b95795203f3ee46f44a197c946e4stevel error = retval_b;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (error);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_bd_unconfigure(int board, sysc_cfga_pkt_t *pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int error;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_handle_t *sh;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_busy(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->sc.type == CPU_BOARD || bdp->sc.type == MEM_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel struct ac_soft_state *acsp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Check that any memory on board is not in use.
29949e866e40b95795203f3ee46f44a197c946e4stevel * This must be done while the board list lock is held
29949e866e40b95795203f3ee46f44a197c946e4stevel * as memory state can change while fhc_bd_busy() is true
29949e866e40b95795203f3ee46f44a197c946e4stevel * even though a memory operation cannot be started
29949e866e40b95795203f3ee46f44a197c946e4stevel * if fhc_bd_busy() is true.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((acsp = (struct ac_soft_state *)bdp->ac_softsp) != NULL) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (acsp->bank[Bank0].busy != 0 ||
29949e866e40b95795203f3ee46f44a197c946e4stevel acsp->bank[Bank0].ostate ==
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_OSTATE_CONFIGURED) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "memory bank %d in "
29949e866e40b95795203f3ee46f44a197c946e4stevel "slot %d is in use.", Bank0, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(pkt->errbuf,
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_OUTPUT_LEN,
29949e866e40b95795203f3ee46f44a197c946e4stevel "memory bank %d in use",
29949e866e40b95795203f3ee46f44a197c946e4stevel Bank0);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EBUSY);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (acsp->bank[Bank1].busy != 0 ||
29949e866e40b95795203f3ee46f44a197c946e4stevel acsp->bank[Bank1].ostate ==
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_OSTATE_CONFIGURED) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "memory bank %d in "
29949e866e40b95795203f3ee46f44a197c946e4stevel "slot %d is in use.", Bank1, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(pkt->errbuf,
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_OUTPUT_LEN,
29949e866e40b95795203f3ee46f44a197c946e4stevel "memory bank %d in use",
29949e866e40b95795203f3ee46f44a197c946e4stevel Bank1);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EBUSY);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Nothing more to do here. The memory interface
29949e866e40b95795203f3ee46f44a197c946e4stevel * will not make any transitions while
29949e866e40b95795203f3ee46f44a197c946e4stevel * fhc_bd_busy() is true. Once the ostate
29949e866e40b95795203f3ee46f44a197c946e4stevel * becomes unconfigured, the memory becomes
29949e866e40b95795203f3ee46f44a197c946e4stevel * invisible.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel error = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->sc.type == CPU_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel struct cpu *cpua, *cpub;
29949e866e40b95795203f3ee46f44a197c946e4stevel int cpu_flags = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (pkt->cmd_cfga.force)
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_flags = CPU_FORCED;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&cpu_lock); /* protects CPU states */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel error = fhc_board_poweroffcpus(board, pkt->errbuf,
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_flags);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel cpua = cpu_get(FHC_BOARD2CPU_A(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel cpub = cpu_get(FHC_BOARD2CPU_B(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((error == 0) && (cpua != NULL)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel error = cpu_unconfigure(cpua->cpu_id);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error != 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(pkt->errbuf,
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_OUTPUT_LEN,
29949e866e40b95795203f3ee46f44a197c946e4stevel "processor %d unconfigure failed",
29949e866e40b95795203f3ee46f44a197c946e4stevel cpua->cpu_id);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((error == 0) && (cpub != NULL)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel error = cpu_unconfigure(cpub->cpu_id);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error != 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(pkt->errbuf,
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_OUTPUT_LEN,
29949e866e40b95795203f3ee46f44a197c946e4stevel "processor %d unconfigure failed",
29949e866e40b95795203f3ee46f44a197c946e4stevel cpub->cpu_id);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error != 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (error);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sh = &bdp->sh[SYSC_DR_HANDLE_DEVS];
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->errstr = pkt->errbuf;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(sh->dip_list == NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_init(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->flags |= SYSC_DR_DEVS;
29949e866e40b95795203f3ee46f44a197c946e4stevel error = sysc_dr_detach(sh, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel sh->flags &= ~SYSC_DR_REMOVE;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_ERR_SET(pkt, SYSC_ERR_NDI_DETACH);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_uninit(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel goto done;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_uninit(sh);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (enable_redist) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel intr_redist_all_cpus();
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&cpu_lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4steveldone:
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (error);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4steveltypedef struct sysc_prom {
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_handle_t *handle; /* DR handle */
29949e866e40b95795203f3ee46f44a197c946e4stevel int board; /* board id */
29949e866e40b95795203f3ee46f44a197c946e4stevel dev_info_t **dipp; /* next slot for storing dip */
29949e866e40b95795203f3ee46f44a197c946e4stevel} sysc_prom_t;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Attaching devices on a board.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_dr_attach(sysc_dr_handle_t *handle, int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel int err;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_prom_t arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel devi_branch_t b = {0};
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel arg.handle = handle;
29949e866e40b95795203f3ee46f44a197c946e4stevel arg.board = board;
29949e866e40b95795203f3ee46f44a197c946e4stevel arg.dipp = handle->dip_list;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel b.arg = &arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel b.type = DEVI_BRANCH_PROM;
29949e866e40b95795203f3ee46f44a197c946e4stevel b.create.prom_branch_select = sysc_prom_select;
29949e866e40b95795203f3ee46f44a197c946e4stevel b.devi_branch_callback = sysc_branch_callback;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->error = e_ddi_branch_create(ddi_root_node(), &b,
29949e866e40b95795203f3ee46f44a197c946e4stevel NULL, DEVI_BRANCH_CHILD);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (handle->error)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (handle->error);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0, arg.dipp = handle->dip_list;
29949e866e40b95795203f3ee46f44a197c946e4stevel i < handle->dip_list_len; i++, arg.dipp++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel err = e_ddi_branch_configure(*arg.dipp, NULL, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Error only if we fail for fhc dips
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (err && (handle->flags & SYSC_DR_FHC)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->error = err;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_dr_err_decode(handle, *arg.dipp, TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (handle->error);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_make_list(void *arg, int has_changed)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel dev_info_t *rdip;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_prom_t *wp = (sysc_prom_t *)arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel pnode_t nid = prom_childnode(prom_rootnode());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (wp == NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EINVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (; nid != OBP_NONODE && nid != OBP_BADNODE;
29949e866e40b95795203f3ee46f44a197c946e4stevel nid = prom_nextnode(nid)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_prom_select(nid, arg, 0) != DDI_SUCCESS)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (wp->handle->dip_list_len < SYSC_DR_MAX_NODE) {
29949e866e40b95795203f3ee46f44a197c946e4stevel rdip = wp->handle->dip_list[wp->handle->dip_list_len] =
29949e866e40b95795203f3ee46f44a197c946e4stevel e_ddi_nodeid_to_dip(nid);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (rdip != NULL) {
29949e866e40b95795203f3ee46f44a197c946e4stevel wp->handle->dip_list_len++;
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Branch rooted at dip already held, so
29949e866e40b95795203f3ee46f44a197c946e4stevel * release hold acquired in e_ddi_nodeid_to_dip
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel ddi_release_devi(rdip);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(e_ddi_branch_held(rdip));
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel DPRINTF(SYSC_DEBUG, ("sysc_make_list:"
29949e866e40b95795203f3ee46f44a197c946e4stevel " e_ddi_nodeid_to_dip() failed for"
29949e866e40b95795203f3ee46f44a197c946e4stevel " nodeid: %d\n", nid));
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "sysc_make_list: list overflow\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EFAULT);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Detaching devices on a board.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_dr_detach(sysc_dr_handle_t *handle, int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t flags;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_prom_t arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(handle->dip_list);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(handle->dip_list_len == 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(*handle->dip_list == NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel arg.handle = handle;
29949e866e40b95795203f3ee46f44a197c946e4stevel arg.board = board;
29949e866e40b95795203f3ee46f44a197c946e4stevel arg.dipp = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->error = prom_tree_access(sysc_make_list, &arg, NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (handle->error)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (handle->error);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel flags = DEVI_BRANCH_DESTROY | DEVI_BRANCH_EVENT;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = handle->dip_list_len; i > 0; i--) {
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(e_ddi_branch_held(handle->dip_list[i - 1]));
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->error = e_ddi_branch_unconfigure(
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->dip_list[i - 1], NULL, flags);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (handle->error)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (handle->error);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_dr_init(sysc_dr_handle_t *handle)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->dip_list = kmem_zalloc(sizeof (dev_info_t *) * SYSC_DR_MAX_NODE,
29949e866e40b95795203f3ee46f44a197c946e4stevel KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->dip_list_len = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED2*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_prom_select(pnode_t pnode, void *arg, uint_t flag)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int bd_id;
29949e866e40b95795203f3ee46f44a197c946e4stevel char name[OBP_MAXDRVNAME];
29949e866e40b95795203f3ee46f44a197c946e4stevel int len;
29949e866e40b95795203f3ee46f44a197c946e4stevel int *regp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_prom_t *wp = (sysc_prom_t *)arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bd_id = -1;
29949e866e40b95795203f3ee46f44a197c946e4stevel len = prom_getproplen(pnode, OBP_REG);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (len > 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel regp = kmem_alloc(len, KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) prom_getprop(pnode, OBP_REG, (caddr_t)regp);
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Get board id for EXXXX platforms where
29949e866e40b95795203f3ee46f44a197c946e4stevel * 0x1c0 is EXXXX platform specific data to
29949e866e40b95795203f3ee46f44a197c946e4stevel * acquire board id.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel bd_id = (*regp - 0x1c0) >> 2;
29949e866e40b95795203f3ee46f44a197c946e4stevel kmem_free(regp, len);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) prom_getprop(pnode, OBP_NAME, (caddr_t)name);
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((bd_id == wp->board) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel ((wp->handle->flags & SYSC_DR_FHC) ?
29949e866e40b95795203f3ee46f44a197c946e4stevel (strcmp(name, "fhc") == 0):
29949e866e40b95795203f3ee46f44a197c946e4stevel (strcmp(name, "fhc") != 0)) &&
29949e866e40b95795203f3ee46f44a197c946e4stevel (strcmp(name, "central") != 0)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel return (DDI_SUCCESS);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (DDI_FAILURE);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*ARGSUSED*/
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_branch_callback(dev_info_t *rdip, void *arg, uint_t flags)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_prom_t *wp = (sysc_prom_t *)arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(wp->dipp != NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(*wp->dipp == NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT((wp->handle->flags & SYSC_DR_REMOVE) == 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (wp->handle->dip_list_len < SYSC_DR_MAX_NODE) {
29949e866e40b95795203f3ee46f44a197c946e4stevel *wp->dipp = rdip;
29949e866e40b95795203f3ee46f44a197c946e4stevel wp->dipp++;
29949e866e40b95795203f3ee46f44a197c946e4stevel wp->handle->dip_list_len++;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "sysc_branch_callback: list overflow");
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Uninitialize devices for the state of a board.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_dr_uninit(sysc_dr_handle_t *handle)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel kmem_free(handle->dip_list,
29949e866e40b95795203f3ee46f44a197c946e4stevel sizeof (dev_info_t *) * SYSC_DR_MAX_NODE);
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->dip_list = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->dip_list_len = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_dr_err_decode(sysc_dr_handle_t *handle, dev_info_t *dip, int attach)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel char *p;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(handle->error != 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (handle->error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case ENOMEM:
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case EBUSY:
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) ddi_pathname(dip, handle->errstr);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->error = EFAULT;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (attach)
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) ddi_pathname(ddi_get_parent(dip),
29949e866e40b95795203f3ee46f44a197c946e4stevel handle->errstr);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) ddi_pathname(dip, handle->errstr);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (attach) {
29949e866e40b95795203f3ee46f44a197c946e4stevel p = "/";
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) strcat(handle->errstr, p);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) strcat(handle->errstr, ddi_node_name(dip));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic char *
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_rstate_typestr(sysc_cfga_rstate_t rstate, sysc_audit_evt_t event)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel char *type_str;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (rstate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (event) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "emptying";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_SUCCEEDED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "emptied";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_EMPTY_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "empty";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "empty?";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_DISCONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (event) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_DISCONNECT:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "disconnecting";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_SUCCEEDED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "disconnected";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_DISCONNECT_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "disconnect";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "disconnect?";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_CONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (event) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_CONNECT:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "connecting";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_SUCCEEDED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "connected";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_CONNECT_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "connect";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "connect?";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "undefined receptacle state";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (type_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic char *
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_ostate_typestr(sysc_cfga_ostate_t ostate, sysc_audit_evt_t event)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel char *type_str;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (ostate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_UNCONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (event) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_UNCONFIGURE:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "unconfiguring";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_SUCCEEDED:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_UNCONFIGURE_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "unconfigured";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "unconfigure?";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_OSTATE_CONFIGURED:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (event) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_CONFIGURE:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "configuring";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_SUCCEEDED:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_CONFIGURE_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "configured";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "configure?";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "undefined occupant state";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (type_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_policy_audit_messages(sysc_audit_evt_t event, sysc_cfga_stat_t *sysc_stat)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (event) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_CONNECT:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s %s board in slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_rstate_typestr(SYSC_CFGA_RSTATE_CONNECTED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event),
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_DISCONNECT:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s %s board in slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_rstate_typestr(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_RSTATE_DISCONNECTED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event),
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_SUCCEEDED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s board in slot %d is %s",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_rstate_typestr(sysc_stat->rstate,
29949e866e40b95795203f3ee46f44a197c946e4stevel event));
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_CONNECT_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s board in slot %d failed to %s",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_rstate_typestr(SYSC_CFGA_RSTATE_CONNECTED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event));
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_RSTATE_DISCONNECT_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s board in slot %d failed to %s",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_rstate_typestr(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_RSTATE_DISCONNECTED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event));
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_CONFIGURE:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s %s board in slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_ostate_typestr(SYSC_CFGA_OSTATE_CONFIGURED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event),
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_UNCONFIGURE:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s %s board in slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_ostate_typestr(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_OSTATE_UNCONFIGURED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event),
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_SUCCEEDED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s board in slot %d is %s",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_ostate_typestr(sysc_stat->ostate,
29949e866e40b95795203f3ee46f44a197c946e4stevel event));
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_CONFIGURE_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s board in slot %d partially %s",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_ostate_typestr(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_OSTATE_CONFIGURED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event));
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_AUDIT_OSTATE_UNCONFIGURE_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "%s board in slot %d partially %s",
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_ostate_typestr(
29949e866e40b95795203f3ee46f44a197c946e4stevel SYSC_CFGA_OSTATE_UNCONFIGURED,
29949e866e40b95795203f3ee46f44a197c946e4stevel event));
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "unknown audit of a %s %s board in"
29949e866e40b95795203f3ee46f44a197c946e4stevel " slot %d",
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_rstate_typestr(sysc_stat->rstate,
29949e866e40b95795203f3ee46f44a197c946e4stevel event),
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_typestr(sysc_stat->type),
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_stat->board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#define MAX_PROP_LEN 33 /* must be > strlen("cpu") */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelfind_and_setup_cpu(int cpuid)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel return (prom_tree_access(find_and_setup_cpu_start, &cpuid, NULL));
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelfind_and_setup_cpu_start(void *cpuid_arg, int has_changed)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel pnode_t nodeid;
29949e866e40b95795203f3ee46f44a197c946e4stevel int upaid;
29949e866e40b95795203f3ee46f44a197c946e4stevel char type[MAX_PROP_LEN];
29949e866e40b95795203f3ee46f44a197c946e4stevel int cpuid = *(int *)cpuid_arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel nodeid = prom_childnode(prom_rootnode());
29949e866e40b95795203f3ee46f44a197c946e4stevel while (nodeid != OBP_NONODE) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (prom_getproplen(nodeid, "device_type") < MAX_PROP_LEN)
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) prom_getprop(nodeid, "device_type",
29949e866e40b95795203f3ee46f44a197c946e4stevel (caddr_t)type);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel type[0] = '\0';
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) prom_getprop(nodeid, "upa-portid", (caddr_t)&upaid);
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((strcmp(type, "cpu") == 0) && (upaid == cpuid)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel return (cpu_configure(cpuid));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel nodeid = prom_nextnode(nodeid);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ENODEV);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#define MAX_BOARD_TYPE IO_SBUS_FFB_SOCPLUS_BOARD
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic char sysc_supp_conn[MAX_BOARD_TYPE + 1];
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_board_connect_supported(enum board_type type)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel if (type > MAX_BOARD_TYPE)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (sysc_supp_conn[type]);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelsysc_board_connect_supported_init(void)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel pnode_t openprom_node;
29949e866e40b95795203f3ee46f44a197c946e4stevel char sup_list[16];
29949e866e40b95795203f3ee46f44a197c946e4stevel int proplen;
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel char tstr[3 * 5 + 1];
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Check the firmware for Dynamic Reconfiguration support */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (prom_test("SUNW,Ultra-Enterprise,rm-brd") != 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* The message was printed in platmod:set_platform_defaults */
29949e866e40b95795203f3ee46f44a197c946e4stevel enable_dynamic_reconfiguration = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel openprom_node = prom_finddevice("/openprom");
29949e866e40b95795203f3ee46f44a197c946e4stevel if (openprom_node != OBP_BADNODE) {
29949e866e40b95795203f3ee46f44a197c946e4stevel proplen = prom_bounded_getprop(openprom_node,
29949e866e40b95795203f3ee46f44a197c946e4stevel "add-brd-supported-types",
29949e866e40b95795203f3ee46f44a197c946e4stevel sup_list, sizeof (sup_list) - 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel proplen = -1;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (proplen < 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This is an old prom which may cause a fatal reset,
29949e866e40b95795203f3ee46f44a197c946e4stevel * so don't allow any DR operations.
29949e866e40b95795203f3ee46f44a197c946e4stevel * If enable_dynamic_reconfiguration is 0
29949e866e40b95795203f3ee46f44a197c946e4stevel * we have already printed a similar message.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (enable_dynamic_reconfiguration) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "Firmware does not support"
29949e866e40b95795203f3ee46f44a197c946e4stevel " Dynamic Reconfiguration");
29949e866e40b95795203f3ee46f44a197c946e4stevel enable_dynamic_reconfiguration = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0; i < proplen; i++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sup_list[i]) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case '0':
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_supp_conn[CPU_BOARD] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_supp_conn[MEM_BOARD] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case '1':
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_supp_conn[IO_2SBUS_BOARD] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case '2':
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_supp_conn[IO_SBUS_FFB_BOARD] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case '3':
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_supp_conn[IO_PCI_BOARD] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case '4':
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_supp_conn[IO_2SBUS_SOCPLUS_BOARD] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case '5':
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_supp_conn[IO_SBUS_FFB_SOCPLUS_BOARD] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Ignore other characters. */
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_supp_conn[CPU_BOARD]) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "!Firmware supports Dynamic Reconfiguration"
29949e866e40b95795203f3ee46f44a197c946e4stevel " of CPU/Memory boards.");
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "Firmware does not support Dynamic"
29949e866e40b95795203f3ee46f44a197c946e4stevel " Reconfiguration of CPU/Memory boards.");
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel tstr[0] = '\0';
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_supp_conn[IO_2SBUS_BOARD])
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) strcat(tstr, ", 1");
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_supp_conn[IO_SBUS_FFB_BOARD])
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) strcat(tstr, ", 2");
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_supp_conn[IO_PCI_BOARD])
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) strcat(tstr, ", 3");
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_supp_conn[IO_2SBUS_SOCPLUS_BOARD])
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) strcat(tstr, ", 4");
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sysc_supp_conn[IO_SBUS_FFB_SOCPLUS_BOARD])
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) strcat(tstr, ", 5");
29949e866e40b95795203f3ee46f44a197c946e4stevel if (tstr[0] != '\0') {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Skip leading ", " using &tstr[2]. */
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "!Firmware supports Dynamic Reconfiguration"
29949e866e40b95795203f3ee46f44a197c946e4stevel " of I/O board types %s.", &tstr[2]);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "Firmware does not support Dynamic"
29949e866e40b95795203f3ee46f44a197c946e4stevel " Reconfiguration of I/O boards.");
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelprecache_regdump(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *curr_bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel int bd_idx;
29949e866e40b95795203f3ee46f44a197c946e4stevel int reg_idx;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bd_idx = 0; bd_idx < fhc_max_boards(); bd_idx++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel bcopy((void *) reg_tmpl, (void *) &reg_dt[bd_idx][0],
29949e866e40b95795203f3ee46f44a197c946e4stevel (sizeof (struct regs_data))*NUM_REG);
29949e866e40b95795203f3ee46f44a197c946e4stevel curr_bdp = fhc_bd(bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (curr_bdp->sc.rstate == SYSC_CFGA_RSTATE_CONNECTED) {
29949e866e40b95795203f3ee46f44a197c946e4stevel for (reg_idx = 0; reg_idx < NUM_REG; reg_idx++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][reg_idx].eflag = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bd_idx != board)
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][reg_idx].oflag = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][reg_idx].physaddr +=
29949e866e40b95795203f3ee46f44a197c946e4stevel (FHC_BOARD_SPAN*2*bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][reg_idx].pre_dsct =
29949e866e40b95795203f3ee46f44a197c946e4stevel ldphysio(reg_dt[bd_idx][reg_idx].physaddr);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelboardstat_regdump(void)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int bd_idx;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("\nBoard status before disconnect.\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bd_idx = 0; bd_idx < fhc_max_boards(); bd_idx++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (reg_dt[bd_idx][0].eflag == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("Board #%d is idle.\n", bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("Board #%d is on.\n", bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bd_idx = 0; bd_idx < fhc_max_boards(); bd_idx++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (reg_dt[bd_idx][0].eflag) {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("\nRegisters for Board #%d", bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf(" (before disconnect).\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("AC_BCSR FHC_CTRL JTAG IGN SIM"
29949e866e40b95795203f3ee46f44a197c946e4stevel " SISM UIM USM\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("%08x %08x %08x %04x"
29949e866e40b95795203f3ee46f44a197c946e4stevel " %08x %04x %08x %04x\n",
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][0].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][1].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][2].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][3].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][4].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][5].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][6].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][7].pre_dsct);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4steveldisplay_regdump(void)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int bd_idx;
29949e866e40b95795203f3ee46f44a197c946e4stevel int reg_idx;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("Board status after disconnect.\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bd_idx = 0; bd_idx < fhc_max_boards(); bd_idx++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (reg_dt[bd_idx][0].oflag == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("Board #%d is idle.\n", bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("Board #%d is on.\n", bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel for (reg_idx = 0; reg_idx < NUM_REG; reg_idx++)
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][reg_idx].post_dsct =
29949e866e40b95795203f3ee46f44a197c946e4stevel ldphysio(reg_dt[bd_idx][reg_idx].physaddr);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bd_idx = 0; bd_idx < fhc_max_boards(); bd_idx++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (reg_dt[bd_idx][0].eflag) {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("\nRegisters for Board #%d", bd_idx);
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf(" (before and after disconnect).\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("AC_BCSR FHC_CTRL JTAG IGN SIM"
29949e866e40b95795203f3ee46f44a197c946e4stevel " SISM UIM USM\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("%08x %08x %08x %04x"
29949e866e40b95795203f3ee46f44a197c946e4stevel " %08x %04x %08x %04x\n",
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][0].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][1].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][2].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][3].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][4].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][5].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][6].pre_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][7].pre_dsct);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (reg_dt[bd_idx][0].oflag) {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("%08x %08x %08x %04x"
29949e866e40b95795203f3ee46f44a197c946e4stevel " %08x %04x %08x %04x\n",
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][0].post_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][1].post_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][2].post_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][3].post_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][4].post_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][5].post_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][6].post_dsct,
29949e866e40b95795203f3ee46f44a197c946e4stevel reg_dt[bd_idx][7].post_dsct);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel prom_printf("no data (board got"
29949e866e40b95795203f3ee46f44a197c946e4stevel " disconnected)-------------------"
29949e866e40b95795203f3ee46f44a197c946e4stevel "---------------\n");
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif /* DEBUG */