1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * CDDL HEADER START
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The contents of this file are subject to the terms of the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Common Development and Distribution License (the "License").
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * You may not use this file except in compliance with the License.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * or http://www.opensolaris.org/os/licensing.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * See the License for the specific language governing permissions
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and limitations under the License.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * When distributing Covered Code, include this CDDL HEADER in each
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * If applicable, add the following below this CDDL HEADER, with the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * fields enclosed by brackets "[]" replaced with your own identifying
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * information: Portions Copyright [yyyy] [name of copyright owner]
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * CDDL HEADER END
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Use is subject to license terms.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv.c - multi-threaded lom driver for the Stiletto platform.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Included files.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/note.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/types.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/param.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/uio.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/open.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/cred.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/stream.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/systm.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/conf.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/reboot.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/modctl.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/mkdev.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/errno.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/debug.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/kmem.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/consdev.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/file.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/stat.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/disp.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/ddi.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/sunddi.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/stream.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/strlog.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/log.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/utsname.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/callb.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/sysevent.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/nvpair.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/sysevent/eventdefs.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/sysevent/domain.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/sysevent/env.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/sysevent/dr.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/lom_io.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/bscbus.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#include <sys/bscv_impl.h>
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Variables defined here and visible internally only
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void *bscv_statep = NULL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Forward declarations
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_attach(dev_info_t *, ddi_attach_cmd_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_detach(dev_info_t *, ddi_detach_cmd_t);
193974072f41a843678abf5f61979c748687e66bSherry Moorestatic int bscv_quiesce(dev_info_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_map_regs(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_unmap_regs(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_map_chan_logical_physical(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_open(dev_t *, int, int, cred_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_close(dev_t, int, int, cred_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_full_stop(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_enter(bscv_soft_state_t *);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.comstatic int bscv_tryenter(bscv_soft_state_t *ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_exit(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef DEBUG
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_held(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* DEBUG */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_put8(bscv_soft_state_t *, int, bscv_addr_t, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_put16(bscv_soft_state_t *, int, bscv_addr_t, uint16_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_put32(bscv_soft_state_t *, int, bscv_addr_t, uint32_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t bscv_get8(bscv_soft_state_t *, int, bscv_addr_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint16_t bscv_get16(bscv_soft_state_t *, int, bscv_addr_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint32_t bscv_get32(bscv_soft_state_t *, int, bscv_addr_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setclear8(bscv_soft_state_t *, int,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_addr_t, uint8_t, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setclear8_volatile(bscv_soft_state_t *, int,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_addr_t, uint8_t, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_rep_rw8(bscv_soft_state_t *, int,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t *, bscv_addr_t, size_t, uint_t, boolean_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t bscv_get8_cached(bscv_soft_state_t *, bscv_addr_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t bscv_get8_locked(bscv_soft_state_t *, int, bscv_addr_t, int *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_rep_get8_locked(bscv_soft_state_t *, int,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t *, bscv_addr_t, size_t, uint_t, int *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_faulty(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_clear_fault(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_set_fault(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_session_error(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_retcode(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_should_retry(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_locked_result(bscv_soft_state_t *, int *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_put8_once(bscv_soft_state_t *, int, bscv_addr_t, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t bscv_get8_once(bscv_soft_state_t *, int, bscv_addr_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint32_t bscv_probe(bscv_soft_state_t *, int, uint32_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_resync_comms(bscv_soft_state_t *, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_window_setup(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_eerw(bscv_soft_state_t *, uint32_t, uint8_t *,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unsigned, boolean_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_dogstate(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_psustate(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_fanstate(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_fledstate(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_ledstate(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_info(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_mread(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_volts(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_stats(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_temp(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_cons(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_eventlog2(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_info2(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_test(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_mprog2(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_ioc_mread2(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_event_daemon(void *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_start_event_daemon(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_stop_event_daemon(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_pause_event_daemon(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_resume_event_daemon(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_event_process(bscv_soft_state_t *ssp, boolean_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_event_validate(bscv_soft_state_t *, uint32_t, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_event_process_one(bscv_soft_state_t *, lom_event_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_build_eventstring(bscv_soft_state_t *,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_event_t *, char *, char *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_level_of_event(lom_event_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_status(bscv_soft_state_t *, uint8_t, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdchar *bscv_get_label(char [][MAX_LOM2_NAME_STR], int, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_generic_sysevent(bscv_soft_state_t *, char *, char *, char *,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *, int32_t, char *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_sysevent(bscv_soft_state_t *, lom_event_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_prog(bscv_soft_state_t *, intptr_t, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_prog_image(bscv_soft_state_t *, boolean_t,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t *, int, uint32_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_prog_receive_image(bscv_soft_state_t *, lom_prog_t *,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t *, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_leave_programming_mode(bscv_soft_state_t *, boolean_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_prog_stop_lom(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_prog_start_lom(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_attach_common(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_cleanup(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_capability(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_probe_check(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_hostname(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_read_hostname(bscv_soft_state_t *, char *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_write_hostname(bscv_soft_state_t *, char *, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_static_info(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t bscv_read_env_name(bscv_soft_state_t *, uint8_t,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t, uint8_t, char [][MAX_LOM2_NAME_STR], int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_events(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_trace(bscv_soft_state_t *, char, const char *,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd const char *, ...);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_idi_init();
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_idi_fini();
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_idi_new_instance(dev_info_t *dip);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_idi_clear_err();
1c42de6d020629af774dd9e9fc81be3f3ed9398egdvoid bscv_idi_set(struct bscv_idi_info info);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_idi_err();
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_nodename_set(struct bscv_idi_info info);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_sig_set(struct bscv_idi_info info);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_wdog_pat(struct bscv_idi_info info);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_wdog_cfg(struct bscv_idi_info info);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_write_sig(bscv_soft_state_t *ssp, bscv_sig_t s);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_watchdog(bscv_soft_state_t *ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_write_wdog_cfg(bscv_soft_state_t *,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint_t, boolean_t, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_inform_bsc(bscv_soft_state_t *, uint32_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_watchdog_pat_request(void *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_watchdog_cfg_request(bscv_soft_state_t *, uint8_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint_t bscv_set_watchdog_timer(bscv_soft_state_t *, uint_t);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_clear_watchdog_timer(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t bscv_panic_callback(void *, int);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_watchdog_cyclic_add(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_watchdog_cyclic_remove(bscv_soft_state_t *);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t wdog_reset_on_timeout = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define WDOG_ON 1
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define WDOG_OFF 0
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define CLK_WATCHDOG_DEFAULT 10 /* 10 seconds */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define WATCHDOG_PAT_INTERVAL 1000000000 /* 1 second */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_watchdog_enable;
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_watchdog_available;
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int watchdog_activated;
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint_t bscv_watchdog_timeout_seconds;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstruct bscv_idi_callout bscv_idi_callout_table[] = {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd {BSCV_IDI_NODENAME, &bscv_nodename_set },
1c42de6d020629af774dd9e9fc81be3f3ed9398egd {BSCV_IDI_SIG, &bscv_sig_set },
1c42de6d020629af774dd9e9fc81be3f3ed9398egd {BSCV_IDI_WDOG_PAT, &bscv_wdog_pat },
1c42de6d020629af774dd9e9fc81be3f3ed9398egd {BSCV_IDI_WDOG_CFG, &bscv_wdog_cfg },
1c42de6d020629af774dd9e9fc81be3f3ed9398egd {BSCV_IDI_NULL, NULL }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd};
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic struct bscv_idi_callout_mgr bscv_idi_mgr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Local Definitions
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define STATUS_READ_LIMIT 8 /* Read up to 8 status changes at a time */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define MYNAME "bscv"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define BSCV_INST_TO_MINOR(i) (i)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define BSCV_MINOR_TO_INST(m) (m)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Strings for daemon event reporting
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic char *eventSubsysStrings[] =
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{ "", /* 00 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Alarm ", /* 01 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "temperature sensor ", /* 02 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "overheat sensor ", /* 03 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Fan ", /* 04 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "supply rail ", /* 05 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "circuit breaker ", /* 06 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "PSU ", /* 07 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "user ", /* 08 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "phonehome ", /* 09; unutilized */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "LOM ", /* 0a */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "host ", /* 0b */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "event log ", /* 0c */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "", /* 0d; EVENT_SUBSYS_EXTRA unutilized */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "LED ", /* 0e */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd};
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic char *eventTypeStrings[] =
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "[null event]", /* 00 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "ON", /* 01 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "OFF", /* 02 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "state change", /* 03 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "power on", /* 04 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "power off", /* 05 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "powered off unexpectedly", /* 06 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "reset unexpectedly", /* 07 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "booted", /* 08 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "watchdog enabled", /* 09 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "watchdog disabled", /* 0a */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "watchdog triggered", /* 0b */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "failed", /* 0c */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "recovered", /* 0d */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "reset", /* 0e */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "XIR reset", /* 0f */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "console selected", /* 10 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "time reference", /* 11 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "script failure", /* 12 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "modem access failure", /* 13 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "modem dialing failure", /* 14 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bad checksum", /* 15 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "added", /* 16 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "removed", /* 17 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "changed", /* 18 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "login", /* 19 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "password changed", /* 1a */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "login failed", /* 1b */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "logout", /* 1c */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "flash download", /* 1d */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "data lost", /* 1e */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "device busy", /* 1f */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "fault led state", /* 20 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "overheat", /* 21 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "severe overheat", /* 22 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "no overheat", /* 23 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "SCC", /* 24 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "device inaccessible", /* 25 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Hostname change", /* 26 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "CPU signature timeout", /* 27 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Bootmode change", /* 28 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Watchdog change policy", /* 29 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Watchdog change timeout", /* 2a */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd};
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * These store to mapping between the logical service, e.g. chan_prog for
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * programming, and the actual Xbus channel which carries that traffic.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Any services can be shared on the same channel apart from chan_wdogpat.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int chan_general; /* General Traffic */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int chan_wdogpat; /* Watchdog Patting */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int chan_cpusig; /* CPU signatures */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int chan_eeprom; /* EEPROM I/O */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int chan_prog; /* Programming */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * cb_ops structure defining the driver entry points
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic struct cb_ops bscv_cb_ops = {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_open, /* open */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_close, /* close */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* strategy */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* print */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* dump */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* read */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* write */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_ioctl, /* ioctl */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* devmap */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* mmap */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodev, /* segmap */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nochpoll, /* poll */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_prop_op, /* prop op */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd NULL, /* ! STREAMS */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd D_NEW | D_MP /* MT/MP Safe */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd};
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * dev_ops structure defining autoconfiguration driver autoconfiguration
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * routines
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic struct dev_ops bscv_dev_ops = {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd DEVO_REV, /* devo_rev */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd 0, /* devo_refcnt */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_getinfo, /* devo_getinfo */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nulldev, /* devo_identify */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nulldev, /* devo_probe */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_attach, /* devo_attach */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_detach, /* devo_detach */
c98f7645b239622b7f69f2bc0b0830dacb78d5f9Zach Kissel nodev, /* devo_reset */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd &bscv_cb_ops, /* devo_cb_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore (struct bus_ops *)0, /* devo_bus_ops */
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL, /* devo_power */
193974072f41a843678abf5f61979c748687e66bSherry Moore bscv_quiesce, /* devo_quiesce */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd};
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * module configuration section
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef DEBUG
193974072f41a843678abf5f61979c748687e66bSherry Moore#define BSCV_VERSION_STRING "bscv driver - Debug"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#else /* DEBUG */
193974072f41a843678abf5f61979c748687e66bSherry Moore#define BSCV_VERSION_STRING "bscv driver"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* DEBUG */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic struct modldrv modldrv = {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd &mod_driverops,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCV_VERSION_STRING,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd &bscv_dev_ops,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd};
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic struct modlinkage modlinkage = {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd MODREV_1,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd &modldrv,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd NULL
1c42de6d020629af774dd9e9fc81be3f3ed9398egd};
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com#ifdef DEBUG
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com/* Tracing is enabled if value is non-zero. */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.comstatic int bscv_trace_flag = 1;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com#define BSCV_TRACE if (bscv_trace_flag != 0) bscv_trace
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com#else
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com#define BSCV_TRACE
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com#endif
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * kernel accessible routines. These routines are necessarily global so the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * driver can be loaded, and unloaded successfully
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - _init
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - initializes the driver state structure and installs the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * driver module into the kernel
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - success or failure of module installation
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdint
1c42de6d020629af774dd9e9fc81be3f3ed9398egd_init(void)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd register int e;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((e = ddi_soft_state_init(&bscv_statep,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (bscv_soft_state_t), 1)) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (e);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((e = mod_install(&modlinkage)) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_soft_state_fini(&bscv_statep);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (e == 0) bscv_idi_init();
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (e);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - _info
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - provide information about a kernel loaded module
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - module infomation
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - success or failure of information request
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdint
1c42de6d020629af774dd9e9fc81be3f3ed9398egd_info(struct modinfo *modinfop)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (mod_info(&modlinkage, modinfop));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - _fini
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - removes a module from the kernel and frees the driver soft
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * state memory
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - success or failure of module removal
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdint
1c42de6d020629af774dd9e9fc81be3f3ed9398egd_fini(void)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd register int e;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((e = mod_remove(&modlinkage)) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (e);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_fini();
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_soft_state_fini(&bscv_statep);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (e);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_getinfo
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - routine used to provide information on the driver
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - device information structure, command, command arg, storage
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * area for the result
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS or DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd dev_t dev = (dev_t)arg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int error;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd instance = DEVICETOINSTANCE(dev);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (cmd) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case DDI_INFO_DEVT2INSTANCE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *result = (void *)(uintptr_t)instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd error = DDI_SUCCESS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case DDI_INFO_DEVT2DEVINFO:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *result = (void *) ssp->dip;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd error = DDI_SUCCESS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd error = DDI_FAILURE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (error);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egdvoid
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_idi_init()
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.valid_inst = (uint32_t)~0; /* No valid instances */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.tbl = bscv_idi_callout_table;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.errs = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Now that all fields are initialized, set the magic flag. This is
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * a kind of integrity check for the data structure.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.magic = BSCV_IDI_CALLOUT_MAGIC;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_idi_clear_err()
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.errs = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_idi_err
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - error messaging service which throttles the number of error
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * messages to avoid overflowing storage
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * returns - boolean to indicate whether a message should be reported
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * side-effects - updates the error number counter
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_idi_err()
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.errs++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_mgr.errs++ < BSCV_IDI_ERR_MSG_THRESHOLD)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdvoid
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_idi_new_instance(dev_info_t *dip)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We don't care how many instances we have, or their value, so long
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * as we have at least one valid value. This is so service routines
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * can get any required locks via a soft state pointer.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_mgr.valid_inst == (uint32_t)~0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.valid_inst = ddi_get_instance(dip);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdvoid
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_idi_fini()
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.valid_inst = (uint32_t)~0; /* No valid instances */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_mgr.tbl = NULL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_attach
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - this routine is responsible for setting aside memory for the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * driver data structures, initialising the mutexes and creating
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the device minor nodes. Additionally, this routine calls the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the callback routine.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - device information structure, DDI_ATTACH command
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS or DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdint
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (cmd) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case DDI_ATTACH:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd instance = ddi_get_instance(dip);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_soft_state_zalloc(bscv_statep, instance) !=
1c42de6d020629af774dd9e9fc81be3f3ed9398egd DDI_SUCCESS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->dip = dip;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->instance = instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_waiting = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->status_change = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->nodename_change = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap0 = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap1 = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap2 = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->programming = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cssp_prog = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->debug = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota DDI_PROP_DONTPASS, "debug", 0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->majornum = ddi_driver_major(dip);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->minornum = BSCV_INST_TO_MINOR(instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->last_nodename[0] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * initialise the mutexes
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_init(&ssp->cmd_mutex, NULL, MUTEX_DRIVER, NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_init(&ssp->task_mu, NULL, MUTEX_DRIVER, NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_init(&ssp->task_cv, NULL, CV_DRIVER, NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_init(&ssp->task_evnt_cv, NULL, CV_DRIVER, NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_init(&ssp->prog_mu, NULL, MUTEX_DRIVER, NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress |= BSCV_LOCKS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_attach",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_attach: mutexes and condition vars initialised");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Map in physical communication channels */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_map_regs(ssp) != DDI_SUCCESS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_cleanup(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress |= BSCV_MAPPED_REGS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Associate logical channels to physical channels */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_map_chan_logical_physical(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_leave_programming_mode(ssp, B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_attach_common(ssp) == DDI_FAILURE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_cleanup(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * At this point the inter-driver-interface is made available.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The IDI uses the event thread service which
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_attach_common() sets up.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_new_instance(dip);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * now create the minor nodes
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_create_minor_node(ssp->dip, "lom", S_IFCHR,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCV_INST_TO_MINOR(instance),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd DDI_PSEUDO, 0) != DDI_SUCCESS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_cleanup(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_attach",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_attach: device minor nodes created");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress |= BSCV_NODES;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->prog_mode_only)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_start_event_daemon(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_enable = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_available = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd watchdog_activated = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_timeout_seconds = CLK_WATCHDOG_DEFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_watchdog_enable && (boothowto & RB_DEBUG)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_available = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "bscv: kernel debugger "
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota "detected: hardware watchdog disabled");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Before we enable the watchdog - register the panic
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * callback so that we get called to stop the watchdog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * in the case of a panic.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->callb_id = callb_add(bscv_panic_callback,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void *)ssp, CB_CL_PANIC, "");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_watchdog_available) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_set_watchdog_timer(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd CLK_WATCHDOG_DEFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_watchdog(ssp); /* starts cyclic callback */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_report_dev(dip);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_detach
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - routine that prepares a module to be unloaded. It undoes all
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the work done by the bscv_attach)() routine. This is
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * facilitated by the use of the progress indicator
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - device information structure, DDI_DETACH command
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS or DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
193974072f41a843678abf5f61979c748687e66bSherry Moore/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * quiesce(9E) entry point.
193974072f41a843678abf5f61979c748687e66bSherry Moore *
193974072f41a843678abf5f61979c748687e66bSherry Moore * This function is called when the system is single-threaded at high
193974072f41a843678abf5f61979c748687e66bSherry Moore * PIL with preemption disabled. Therefore, this function must not be
193974072f41a843678abf5f61979c748687e66bSherry Moore * blocked.
193974072f41a843678abf5f61979c748687e66bSherry Moore *
193974072f41a843678abf5f61979c748687e66bSherry Moore * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
193974072f41a843678abf5f61979c748687e66bSherry Moore * DDI_FAILURE indicates an error condition and should almost never happen.
193974072f41a843678abf5f61979c748687e66bSherry Moore */
193974072f41a843678abf5f61979c748687e66bSherry Moorestatic int
193974072f41a843678abf5f61979c748687e66bSherry Moorebscv_quiesce(dev_info_t *dip)
193974072f41a843678abf5f61979c748687e66bSherry Moore{
193974072f41a843678abf5f61979c748687e66bSherry Moore bscv_soft_state_t *ssp;
193974072f41a843678abf5f61979c748687e66bSherry Moore int instance;
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore instance = ddi_get_instance(dip);
193974072f41a843678abf5f61979c748687e66bSherry Moore ssp = ddi_get_soft_state(bscv_statep, instance);
193974072f41a843678abf5f61979c748687e66bSherry Moore if (ssp == NULL) {
193974072f41a843678abf5f61979c748687e66bSherry Moore return (DDI_FAILURE);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com#ifdef DEBUG
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com /* Disable tracing, as we are executing at High-Interrupt level */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com bscv_trace_flag = 0;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com#endif
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com /* quiesce the device */
193974072f41a843678abf5f61979c748687e66bSherry Moore bscv_full_stop(ssp);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com
193974072f41a843678abf5f61979c748687e66bSherry Moore return (DDI_SUCCESS);
193974072f41a843678abf5f61979c748687e66bSherry Moore}
193974072f41a843678abf5f61979c748687e66bSherry Moore
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * cb_ops routines
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_open
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - routine to provide association between user fd and device
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * minor number. This routine is necessarily simple since a
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * read/write interface is not provided. Additionally, the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * driver does not enforce exclusive access (FEXCL) or
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * non-blocking during an open (FNDELAY). Deferred attach is
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * supported.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - device number, flag specifying open type, device type,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * permissions
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - success or failure of operation
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_open(dev_t *devp, int flag, int otype, cred_t *cred)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd instance = DEVICETOINSTANCE(*devp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENXIO); /* not attached yet */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'O', "bscv_open", "instance 0x%x", instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (otype != OTYP_CHR) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EINVAL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_close
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - routine to perform the final close on the device. As per the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * open routine, neither FEXCL or FNDELAY accesses are enforced
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * by the driver.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - device number,flag specifying open type, device type,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * permissions
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - success or failure of operation
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED1*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_close(dev_t dev, int flag, int otype, cred_t *cred)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd instance = DEVICETOINSTANCE(dev);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENXIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'O', "bscv_close", "instance 0x%x", instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_map_regs(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int *props;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unsigned int nelements;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->nchannels = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Work out how many channels are available by looking at the number
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * of elements of the regs property array.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, ssp->dip,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota DDI_PROP_DONTPASS, "reg", &props, &nelements);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* We don't need props anymore. Free memory if it was allocated */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (retval == DDI_PROP_SUCCESS)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_prop_free(props);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Check for sanity of nelements */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (retval != DDI_PROP_SUCCESS) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_map_regs", "lookup reg returned"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " 0x%x", retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto cleanup_exit;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (nelements % LOMBUS_REGSPEC_SIZE != 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_map_regs", "nelements %d not"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " a multiple of %d", nelements, LOMBUS_REGSPEC_SIZE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto cleanup_exit;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (nelements > BSCV_MAXCHANNELS * LOMBUS_REGSPEC_SIZE) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_map_regs", "nelements %d too large"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ", probably a misconfiguration", nelements);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto cleanup_exit;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (nelements < BSCV_MINCHANNELS * LOMBUS_REGSPEC_SIZE) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_map_regs", "nelements %d too small"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ", need to have at least a general and a wdog channel",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nelements);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto cleanup_exit;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->nchannels = nelements / LOMBUS_REGSPEC_SIZE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->nchannels; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = ddi_regs_map_setup(ssp->dip, i,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (caddr_t *)&ssp->channel[i].regs,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota 0, 0, &ssp->attr, &ssp->channel[i].handle);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (retval != DDI_SUCCESS) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_map_regs", "map failure"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " 0x%x on space %d", retval, i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Rewind all current mappings - avoiding failed one */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd i--;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (; i >= 0; i--) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_regs_map_free(&ssp->channel[i].handle);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto cleanup_exit;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdcleanup_exit:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * It is important to set nchannels to 0 even if, say, only one of
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the two required handles was mapped. If we cannot achieve our
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * minimum config its not safe to do any IO; this keeps our failure
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * mode handling simpler.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->nchannels = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_unmap_regs(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->nchannels; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_regs_map_free(&ssp->channel[i].handle);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Map logical services onto physical XBus channels.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_map_chan_logical_physical(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We can assert that there will always be at least two channels,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * to allow watchdog pats to be segregated from all other traffic.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_general = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_wdogpat = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * By default move all other services onto the generic channel unless
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the hardware supports additional channels.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_cpusig = chan_eeprom = chan_prog = chan_general;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->nchannels > 2)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_cpusig = 2;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->nchannels > 3)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_eeprom = 3;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->nchannels > 4)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_prog = 4;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_full_stop
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - gracefully shut the lom down during panic or reboot.
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * Disables the watchdog and sets up serial event reporting.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdvoid
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_full_stop(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t bits2set = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t bits2clear = 0;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com int obtained_lock;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'W', "bscv_full_stop",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "turning off watchdog");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com /*
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * Obtain the softstate lock only if it is not already owned,
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * as this function can be called from a High-level interrupt
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * context. As a result, our thread cannot sleep.
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * At end of function, our thread releases the lock only if
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * it acquired the lock.
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com obtained_lock = (bscv_tryenter(ssp) != 0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_in_panic()) {
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bscv_inform_bsc(ssp, BSC_INFORM_PANIC);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bscv_inform_bsc(ssp, BSC_INFORM_OFFLINE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* set serial event reporting */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (ssp->serial_reporting) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_SER_EVENTS_ON:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_SER_EVENTS_DEF:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Make sure serial event reporting is on */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2clear = EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_SER_EVENTS_OFF:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Make sure serial event reporting is on */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2set = EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setclear8_volatile(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_ALARM, bits2set, bits2clear);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com /* Do not free the lock if our thread did not obtain it. */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com if (obtained_lock != 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com bscv_exit(ssp);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOM I/O routines.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * locking
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Two sets of routines are provided:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * normal - must be called after acquiring an appropriate lock.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * locked - perform all the locking required and return any error
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * code in the supplied 'res' argument. If there is no
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * error 'res' is not changed.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The locked routines are designed for use in ioctl commands where
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * only a single operation needs to be performed and the overhead of
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * locking and result checking adds significantly to code complexity.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * locking primitives
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * bscv_enter() - acquires an I/O lock for the calling thread.
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * bscv_tryenter() - conditionally acquires an I/O lock for calling thread.
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * bscv_exit() - releases an I/O lock acquired by bscv_enter().
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com * bscv_held() - used to assert ownership of an I/O lock.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * normal I/O routines
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note bscv_{put|get}{16|32} routines are big-endian. This assumes that
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the firmware works that way too.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_put8(), bscv_put16, bscv_put32 - write values to the LOM
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and handle any retries if necessary.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 16 and 32 bit values are big-endian.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_get8(), bscv_get16, bscv_get32 - read values from the LOM
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and handle any retries if necessary.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 16 and 32 bit values are big-endian.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_setclear8() - set or clear the specified bits in the register
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * at the supplied address.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_setclear8_volatile() - set or clear the specified bits in the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * register at the supplied address. If the lom reports
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * that the registers has changed since the last read
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * re-read and apply the set or clear to the new bits.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_get8_cached() - Return a cached register value (addr < 0x80).
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Does not access the hardware. A read of the hardware
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * automatically updates this cache.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * locked I/O routines
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_get8_locked(), bscv_rep_get8_locked().
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Call the indicated function from above, but wrapping it with
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_enter()/bscv_exit().
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Fault management
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOM communications fault are grouped into three categories:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 1) Faulty - the LOM is not responding and no attempt to communicate
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * with it should be made.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 2) Transient fault - something which might recover after a retry
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * but which doesn't affect our ability to perform other
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * commands.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 3) Command error - an inappropriate command was executed. A retry
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * will not fix it but the command failed.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The current implementation of the bscv driver is not very good at
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * noticing command errors due to the structure of the original code
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * that it is based on. It is possible to extend the driver to do this
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and would probably involve having a concept of a "session error"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * which is less severe than a fault but means that a sequence of
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * commands had some fault which cannot be recovered.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * faults
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_faulty() - returns B_TRUE if the LOM (communications) have been
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * declared faulty.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_clear_fault() - marks the LOM as not faulty.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_set_fault() - marks the LOM as being faulty.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_clear_fault and bscv_set_fault should generally not be called
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * directly.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * command errors/transient faults
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_retcode() - returns the actual error code of the last operation.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_should_retry() - determines if last operation may suceed if
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * retried.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_locked_result() - Set the result of a locked register access.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * low level I/O primitives
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * These are generally not called directly. These perform a single
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * access to the LOM device. They do not handle retries.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_put8_once()
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_get8_once()
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_probe() - perform a probe (NOP) operation to check out lom comms.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_resync_comms() - resynchronise communications after a transient fault.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_enter(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_enter", "");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->cmd_mutex);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_session_error = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.comstatic int
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.combscv_tryenter(bscv_soft_state_t *ssp)
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com{
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com int rv;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_tryenter", "");
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com if ((rv = mutex_tryenter(&ssp->cmd_mutex)) != 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com ssp->had_session_error = B_FALSE;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com return (rv);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com}
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_exit(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->cmd_mutex);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_exit", "");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef DEBUG
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_held(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (mutex_owned(&ssp->cmd_mutex));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* DEBUG */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_put8(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint8_t val)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t needretry;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int num_failures;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_put8",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x <= 0x%02x", addr >> 8, addr & 0xff, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (num_failures = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures < BSC_FAILURE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8_once(ssp, chan, addr, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = bscv_should_retry(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->command_error != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_session_error = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Failure - we ran out of retries */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "bscv_put8: addr 0x%x.%02x retried "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "write %d times, giving up",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_set_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (num_failures > 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'R', "bscv_put8",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x retried write %d times, succeeded",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_put16(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint16_t val)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_put16",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x <= %04x", addr >> 8, addr & 0xff, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, addr, val >> 8);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, addr + 1, val & 0xff);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_put32(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint32_t val)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_put32",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x <= %08x", addr >> 8, addr & 0xff, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, addr, (val >> 24) & 0xff);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, addr + 1, (val >> 16) & 0xff);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, addr + 2, (val >> 8) & 0xff);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, addr + 3, val & 0xff);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get8(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t needretry;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int num_failures;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (num_failures = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures < BSC_FAILURE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get8_once(ssp, chan, addr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = bscv_should_retry(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->command_error != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_session_error = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Failure */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "bscv_get8: addr 0x%x.%02x retried "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "read %d times, giving up",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_set_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (num_failures > 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'R', "bscv_get8",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x retried read %d times, succeeded",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_get8",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x => %02x", addr >> 8, addr & 0xff, retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint16_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get16(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get8(ssp, chan, addr) << 8;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval |= bscv_get8(ssp, chan, addr + 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_get16",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x => %04x", addr >> 8, addr & 0xff, retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint32_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get32(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get8(ssp, chan, addr) << 24;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval |= bscv_get8(ssp, chan, addr + 1) << 16;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval |= bscv_get8(ssp, chan, addr + 2) << 8;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval |= bscv_get8(ssp, chan, addr + 3);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_get32",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x => %08x", addr >> 8, addr & 0xff, retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_setclear8(bscv_soft_state_t *ssp, int chan,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_addr_t addr, uint8_t set, uint8_t clear)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t val;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(addr < BSC_ADDR_CACHE_LIMIT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd val = ssp->lom_regs[addr] | set;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd val &= ~clear;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_setclear8",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x, set %02x, clear %02x => %02x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd set, clear, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, addr, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_setclear8_volatile(bscv_soft_state_t *ssp, int chan,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_addr_t addr, uint8_t set, uint8_t clear)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t val;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t needretry;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int num_failures;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(addr < BSC_ADDR_CACHE_LIMIT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_setclear8_volatile",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x => set %02x clear %02x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, set, clear);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd val = bscv_get8_cached(ssp, addr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (num_failures = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures < BSC_FAILURE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd val |= set;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd val &= ~clear;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8_once(ssp, chan, addr, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->command_error == EBUS_ERROR_STALEDATA) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Re-read the stale register from the lom */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd val = bscv_get8_once(ssp, chan, addr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = bscv_should_retry(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->command_error != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_session_error = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Failure */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "bscv_setclear8_volatile: addr 0x%x.%02x "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "retried write %d times, giving up",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->command_error != EBUS_ERROR_STALEDATA) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_set_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (num_failures > 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'R', "bscv_setclear8_volatile",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x retried write %d times, succeeded",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_rep_rw8(bscv_soft_state_t *ssp, int chan, uint8_t *host_addr,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_addr_t dev_addr, size_t repcount, uint_t flags,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t is_write)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size_t inc;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd inc = (flags & DDI_DEV_AUTOINCR) ? 1 : 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (; repcount--; dev_addr += inc) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (flags & DDI_DEV_AUTOINCR) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (is_write) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan, dev_addr, *host_addr++);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *host_addr++ = bscv_get8(ssp, chan, dev_addr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (is_write) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8_once(ssp, chan,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota dev_addr, *host_addr++);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *host_addr++ = bscv_get8_once(ssp, chan,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota dev_addr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* We need this because _once routines don't do it */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->command_error != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_session_error = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || bscv_session_error(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * No retry here. If we were AUTOINCR then get/put
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * will have retried. For NO_AUTOINCR we cannot retry
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * because the data would be corrupted.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get8_cached(bscv_soft_state_t *ssp, bscv_addr_t addr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(addr < BSC_ADDR_CACHE_LIMIT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Can be called with or without the lock held */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ssp->lom_regs[addr]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get8_locked(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, int *res)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(addr < BSC_ADDR_CACHE_LIMIT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get8(ssp, chan, addr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_locked_result(ssp, res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_get8_locked",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x => %02x", addr >> 8, addr & 0xff, retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_rep_get8_locked(bscv_soft_state_t *ssp, int chan, uint8_t *host_addr,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_addr_t dev_addr, size_t repcount, uint_t flags, int *res)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_rep_rw8(ssp, chan, host_addr, dev_addr, repcount,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd flags, B_FALSE /* read */);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_locked_result(ssp, res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_faulty(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ssp->had_fault);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_clear_fault(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'J', "bscv_clear_fault", "clearing fault flag");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_fault = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_session_error = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_set_fault(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'J', "bscv_set_fault", "setting fault flag");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_fault = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_session_error(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ssp->had_session_error);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_retcode(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_retcode",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "code 0x%x", ssp->command_error);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ssp->command_error);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_should_retry(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((ssp->command_error == EBUS_ERROR_DEVICEFAIL) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ssp->command_error >= LOMBUS_ERR_BASE)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* This command is due to an I/O fault - retry might fix */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The command itself was bad - there is no point in fixing
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note. Whatever happens we should know that if we were
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * doing EBUS_IDX_SELFTEST0..EBUS_IDX_SELFTEST7 and we
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * had 0x80 set then this is a test error not a retry
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * error.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_locked_result(bscv_soft_state_t *ssp, int *res)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || (bscv_retcode(ssp) != 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_put8_once(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint8_t val)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t fault;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->command_error = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Bail out things are not working */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->nchannels == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Didn't manage to map handles so ddi_{get,put}* broken */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_put8_once",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nchannels is 0x0 so cannot do IO");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Clear any pending fault */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_put32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG), 0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Do the access and get fault code - may take a long time */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_put8(ssp->channel[chan].handle,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &ssp->channel[chan].regs[addr], val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault = ddi_get32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->command_error = fault;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (fault == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Things were ok - update cache entry */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (addr < BSC_ADDR_CACHE_LIMIT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Store cacheable entries */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->lom_regs[addr] = val;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (fault >= LOMBUS_ERR_BASE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* lombus problem - do a resync session */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_put8_once: Had comms fault "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "for address 0x%x.%02x - data 0x%x, fault 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, val, fault);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Attempt to resync with the lom */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_resync_comms(ssp, chan);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note: we do not set fault status here. That
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * is done if our caller decides to give up talking to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the lom. The observant might notice that this means
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * that if we mend things on the last attempt we still
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * get the fault set - we just live with that!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_put8_once",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x <= 0x%02x", addr >> 8, addr & 0xff, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get8_once(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t val;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t fault;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->command_error = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Bail out things are not working */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0xff);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->nchannels == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Didn't manage to map handles so ddi_{get,put}* broken */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_get8_once",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nchannels is 0x0 so cannot do IO");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0xff);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Clear any pending fault */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_put32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG), 0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Do the access and get fault code - may take a long time */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd val = ddi_get8(ssp->channel[chan].handle,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &ssp->channel[chan].regs[addr]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault = ddi_get32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->command_error = fault;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (fault >= LOMBUS_ERR_BASE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* lombus problem - do a resync session */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_get8_once: Had comms fault "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "for address 0x%x.%02x - data 0x%x, fault 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr >> 8, addr & 0xff, val, fault);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Attempt to resync with the lom */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_resync_comms(ssp, chan);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note: we do not set fault status here. That
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * is done if our caller decides to give up talking to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the lom. The observant might notice that this means
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * that if we mend things on the last attempt we still
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * get the fault set - we just live with that!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * FIXME - should report error if you get
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * EBUS_ERROR_DEVICEFAIL reported from the BSC. That gets
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * logged as a failure in bscv_should_retry and may contribute
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * to a permanent failure. Reference issues seen by Mitac.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (addr < BSC_ADDR_CACHE_LIMIT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Store cacheable entries */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->lom_regs[addr] = val;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_get8_once",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "addr 0x%x.%02x => 0x%02x", addr >> 8, addr & 0xff, val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (val);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint32_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_probe(bscv_soft_state_t *ssp, int chan, uint32_t *fault)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t async_reg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->nchannels == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Failed to map handles, so cannot do any IO. Set the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * fault indicator and return a dummy value.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_probe",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nchannels is 0x0 so cannot do any IO");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *fault = LOMBUS_ERR_REG_NUM;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return ((~(int8_t)0));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Clear faults */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_put32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG), 0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Probe and Check faults */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *fault = ddi_get32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_PROBE_REG));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Read status */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd async_reg = ddi_get32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_ASYNC_REG));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_probe",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "async status 0x%x, fault 0x%x", async_reg, *fault);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (async_reg);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_resync_comms(bscv_soft_state_t *ssp, int chan)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int try;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t command_error = ssp->command_error;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t fault = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->nchannels == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Didn't manage to map handles so ddi_{get,put}* broken.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Therefore, there is no way to resync comms.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, '@', "bscv_resync_comms",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nchannels is 0x0 so not possible to resync comms");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (command_error >= LOMBUS_ERR_BASE &&
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota command_error != LOMBUS_ERR_REG_NUM &&
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota command_error != LOMBUS_ERR_REG_SIZE &&
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota command_error != LOMBUS_ERR_TIMEOUT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Resync here to make sure that the lom is talking */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_resync_comms: "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Attempting comms resync after comms fault 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd command_error);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (try = 1; try <= 8; try++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Probe */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault = ddi_get32(ssp->channel[chan].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota LOMBUS_PROBE_REG));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (fault == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_resync_comms: "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "comms resync (probing) - try 0x%x "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "had fault 0x%x", try, fault);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (fault != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_resync_comms: "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Failed to resync comms - giving up");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->bad_resync++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_resync_comms: "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "resync comms after 0x%x tries", try);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->bad_resync = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMLite configuration/event eeprom access routines
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_window_setup() - Read/Sanity check the eeprom parameters.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This must be called prior to calling bscv_eerw().
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_eerw() - Read/write data from/to the eeprom.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_window_setup
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - this routine reads the eeprom parameters and sanity
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * checks them to ensure that the lom is talking sense.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - B_TRUE if the eeprom is ok, B_FALSE if the eeprom is not OK.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_window_setup(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->eeinfo_valid) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Already have good cached values */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ssp->eeinfo_valid);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eeprom_size =
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bscv_get8(ssp, chan_general, EBUS_IDX_EEPROM_SIZE_KB) * 1024;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eventlog_start = bscv_get16(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_LOG_START_HI);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The log does not run to the end of the EEPROM because it is a
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * logical partition. The last 8K partition is reserved for FRUID
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * usage.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eventlog_size = EBUS_LOG_END - ssp->eventlog_start;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'I', "bscv_window_setup", "eeprom size 0x%x log_start"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " 0x%x log_size 0x%x", ssp->eeprom_size, ssp->eventlog_start,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eventlog_size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || bscv_session_error(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eeinfo_valid = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((ssp->eeprom_size == 0) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ssp->eventlog_start >= ssp->eeprom_size)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Sanity check values */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "!bscv_window_setup: read invalid eeprom parameters");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eeinfo_valid = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eeinfo_valid = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'I', "bscv_window_setup", "returning eeinfo_valid %s",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eeinfo_valid ? "true" : "false");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ssp->eeinfo_valid);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_eerw
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - this routine reads/write data from/to the eeprom.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * It takes care of setting the window on the eeprom correctly.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr, eeprom offset, data buffer, size, read/write
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - B_TRUE if the eeprom is ok, B_FALSE if the eeprom is not OK.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_eerw(bscv_soft_state_t *ssp, uint32_t eeoffset, uint8_t *buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unsigned size, boolean_t is_write)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t blk_addr = eeoffset;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unsigned remaining = size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t page_idx;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t this_page;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t blk_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (remaining > 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd page_idx = blk_addr & 0xff;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((page_idx + remaining) > 0x100) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd blk_size = 0x100 - page_idx;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd blk_size = remaining;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Select correct eeprom page */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd this_page = blk_addr >> 8;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_eeprom, EBUS_IDX_EEPROM_PAGESEL, this_page);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'M', "lom_eerw",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "%s data @0x%x.%02x, size 0x%x, 0x%x bytes remaining",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd is_write ? "writing" : "reading",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd this_page, page_idx, blk_size, remaining - blk_size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_rep_rw8(ssp, chan_eeprom,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf, BSCVA(EBUS_CMD_SPACE_EEPROM, page_idx),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd blk_size, DDI_DEV_AUTOINCR, is_write);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || bscv_session_error(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd remaining -= blk_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd blk_addr += blk_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += blk_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_is_null_event(bscv_soft_state_t *ssp, lom_event_t *e)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(e != NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (EVENT_DECODE_SUBSYS(e->ev_subsys) == EVENT_SUBSYS_NONE &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd e->ev_event == EVENT_NONE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This marks a NULL event.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_is_null_event",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "EVENT_SUBSYS_NONE/EVENT_NONE null event");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (e->ev_subsys == 0xff && e->ev_event == 0xff) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Under some circumstances, we've seen all 1s to represent
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * a manually cleared event log at the BSC prompt. Only
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * a test/diagnosis environment is likely to show this.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_is_null_event", "0xffff null event");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Not a NULL event.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_is_null_event", "returning False");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * IOCTL Processing
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_ioctl
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - routine that acts as a high level manager for ioctls. It
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * calls the appropriate handler for ioctls on the alarm:mon and
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * alarm:ctl minor nodes respectively
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Unsupported ioctls (now deprecated)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCALCTL
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCALSTATE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCCLEARLOG
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCCTL
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCCTL2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCDAEMON
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCDMON
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCDOGCTL, TSIOCDOGCTL
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCDOGPAT, TSIOCDOGPAT
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCDOGTIME, TSIOCDOGTIME
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCEVENTLOG
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCEVNT
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCGETMASK
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCMPROG
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCNBMON, TSIOCNBMON
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCSLEEP
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCUNLOCK, TSIOCUNLOCK
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCWTMON, TSIOCWTMON
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Supported ioctls
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCDOGSTATE, TSIOCDOGSTATE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCPROG
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCPSUSTATE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCFANSTATE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCFLEDSTATE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCINFO
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCMREAD
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCVOLTS
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCSTATS
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCTEMP
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCCONS
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCEVENTLOG2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCINFO2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCTEST
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCMPROG2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCMREAD2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - device number, command, user space arg, filemode, user
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * credentials, return value
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - the return value propagated back by the lower level routines.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred, int *rvalp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd instance = DEVICETOINSTANCE(dev);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENXIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The Combined Switch and Service Processor takes care of configuration
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and control. The CSSP tells the BSC chip about it; therefore the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv driver doesn't send such configuration and control to the BSC.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Additionally Watchdog configuration is no longer done from userland
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * lom.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (cmd) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCALCTL:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCALSTATE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCCLEARLOG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCCTL:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCCTL2:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCDAEMON:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCDMON:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCDOGCTL:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCDOGPAT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCDOGTIME:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCEVENTLOG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCEVNT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCGETMASK:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCMPROG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCNBMON:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCSLEEP:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCUNLOCK:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCWTMON:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENOTSUP);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * set the default result.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *rvalp = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->cssp_prog) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENXIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((ssp->prog_mode_only || ssp->programming) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmd != LOMIOCPROG) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENXIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Check that the caller has appropriate access permissions
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * (FWRITE set in mode) for those ioctls which change lom
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * state
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!(mode & FWRITE)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (cmd) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCMPROG2:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCMREAD2:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCPROG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCTEST:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EACCES);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* NOTREACHED */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Does not require write access */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (cmd) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCDOGSTATE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_dogstate(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCPROG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_prog(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCPSUSTATE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_psustate(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCFANSTATE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_fanstate(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCFLEDSTATE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_fledstate(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCLEDSTATE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_ledstate(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCINFO:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_info(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCMREAD:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_mread(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCVOLTS:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_volts(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCSTATS:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_stats(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCTEMP:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_temp(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCCONS:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_cons(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCEVENTLOG2:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_eventlog2(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCINFO2:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_info2(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCTEST:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_test(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCMPROG2:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_mprog2(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOMIOCMREAD2:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_ioc_mread2(ssp, arg, mode);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'I', "bscv_ioctl", "Invalid IOCTL 0x%x", cmd);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EINVAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCDOGSTATE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * TSIOCDOGSTATE - indicate whether the alarm watchdog and reset
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * circuitry is enabled or not.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_dogstate(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_dogstate_t dogstate;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t dogval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd dogval = bscv_get8_locked(ssp, chan_general, EBUS_IDX_WDOG_CTRL, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd dogstate.dog_enable = (dogval & EBUS_WDOG_ENABLE) ? 1 : 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd dogstate.reset_enable = (dogval & EBUS_WDOG_RST) ? 1 : 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd dogstate.dog_timeout = bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_WDOG_TIME, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&dogstate,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (caddr_t)arg, sizeof (dogstate), mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCPSUSTATE - returns full information for 4 PSUs. All this
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * information is available from two bytes of LOMlite RAM, but if
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * on the first read it is noticed that two or more of the PSUs are
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * not present only 1 byte will be read subsequently.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_psustate(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_psudata_t psudata;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t psustat;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < MAX_PSUS; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd psustat = bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_PSU1_STAT + i, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd psudata.fitted[i] = psustat & EBUS_PSU_PRESENT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd psudata.output[i] = psustat & EBUS_PSU_OUTPUT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd psudata.supplyb[i] = psustat & EBUS_PSU_INPUTB;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd psudata.supplya[i] = psustat & EBUS_PSU_INPUTA;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd psudata.standby[i] = psustat & EBUS_PSU_STANDBY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyout((caddr_t)&psudata, (caddr_t)arg, sizeof (psudata),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCFANSTATE - returns full information including speed for 4
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * fans and the minimum and maximum operating speeds for each fan as
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * stored in the READ ONLY EEPROM data. As this EEPROM data is set
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * at manufacture time, this data should only be read by the driver
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * once and stored locally.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_fanstate(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_fandata_t fandata;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int numfans;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(&fandata, sizeof (lom_fandata_t));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd numfans = EBUS_CONFIG_NFAN_DEC(bscv_get8_locked(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_general, EBUS_IDX_CONFIG, &res));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; (i < numfans) && (res == 0); i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->fanspeed[i] != LOM_FAN_NOT_PRESENT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fandata.fitted[i] = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fandata.speed[i] = ssp->fanspeed[i];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fandata.minspeed[i] = bscv_get8_cached(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX_FAN1_LOW + i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&fandata, (caddr_t)arg, sizeof (fandata),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCFLEDSTATE - returns the state of the fault LED
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_fledstate(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_fled_info_t fled_info;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t fledstate;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fledstate = bscv_get8_locked(ssp, chan_general, EBUS_IDX_ALARM, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Decode of 0x0F is off and 0x00-0x07 is on. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (EBUS_ALARM_LED_DEC(fledstate) == 0x0F) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fled_info.on = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* has +1 here - not 2 as in the info ioctl */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fled_info.on = EBUS_ALARM_LED_DEC(fledstate) + 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&fled_info, (caddr_t)arg,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota sizeof (fled_info), mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCLEDSTATE - returns the state of the requested LED
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_ledstate(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_led_state_t led_state;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int fw_led_state;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* copy in arguments supplied */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyin((caddr_t)arg, (caddr_t)&led_state,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (lom_led_state_t), mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * check if led index is -1, if so set it to max value for
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * this implementation.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (led_state.index == -1) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.index = MAX_LED_ID;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* is the index in a valid range */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((led_state.index > MAX_LED_ID) || (led_state.index < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.state = LOM_LED_OUTOFRANGE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* read the relevant led info */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fw_led_state = bscv_get8_locked(ssp, chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX_LED1_STATUS + led_state.index, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* set the state values accordingly */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (fw_led_state) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_OFF:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.state = LOM_LED_OFF;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.colour = LOM_LED_COLOUR_ANY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_ON_STEADY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.state = LOM_LED_ON;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.colour = LOM_LED_COLOUR_ANY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_ON_FLASHING:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_ON_SLOWFLASH:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.state = LOM_LED_BLINKING;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.colour = LOM_LED_COLOUR_ANY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_NOT_PRESENT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.state = LOM_LED_NOT_IMPLEMENTED;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.colour = LOM_LED_COLOUR_NONE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_INACCESSIBLE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_STANDBY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.state = LOM_LED_ACCESS_ERROR;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd led_state.colour = LOM_LED_COLOUR_NONE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* set the label info */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) strcpy(led_state.label,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->led_names[led_state.index]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* copy out lom_state */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&led_state, (caddr_t)arg,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota sizeof (lom_led_state_t), mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCINFO - returns with a structure containing any information
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * stored on the LOMlite which a user should not need to access but
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * may be useful for diagnostic problems. The structure contains: the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * serial escape character, alarm3 mode, version and checksum read from
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * RAM and the Product revision and ID read from EEPROM.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_info(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_info_t info;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t csum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.ser_char = bscv_get8_locked(ssp, chan_general, EBUS_IDX_ESCAPE,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.a3mode = WATCHDOG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.fver = bscv_get8_locked(ssp, chan_general, EBUS_IDX_FW_REV, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd csum = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_HI, &res)
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota << 8;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd csum |= bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_LO, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.fchksum = csum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.prod_rev = bscv_get8_locked(ssp, chan_general, EBUS_IDX_MODEL_REV,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < sizeof (info.prod_id); i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.prod_id[i] = bscv_get8_locked(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_general, EBUS_IDX_MODEL_ID1 + i, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_ALARM, &res) &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_ALARM_NOEVENTS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.events = OFF;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.events = ON;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&info, (caddr_t)arg, sizeof (info),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCMREAD - used to query the LOMlite configuration parameters
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_mread(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_mprog_t mprog;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int fanz;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < sizeof (mprog.mod_id); i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mprog.mod_id[i] = bscv_get8_locked(ssp, chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX_MODEL_ID1 + i, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mprog.mod_rev = bscv_get8_locked(ssp, chan_general, EBUS_IDX_MODEL_REV,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mprog.config = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CONFIG,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Read the fan calibration values */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fanz = sizeof (mprog.fanhz) / sizeof (mprog.fanhz[0]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < fanz; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mprog.fanhz[i] = bscv_get8_cached(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX_FAN1_CAL + i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mprog.fanmin[i] = bscv_get8_cached(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX_FAN1_LOW + i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&mprog, (caddr_t)arg, sizeof (mprog),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCVOLTS
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_volts(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t supply;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd supply = (bscv_get8_locked(ssp, chan_general, EBUS_IDX_SUPPLY_HI, &res)
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota << 8) | bscv_get8_locked(ssp, chan_general, EBUS_IDX_SUPPLY_LO,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->volts.num; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->volts.status[i] = (supply >> i) & 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&ssp->volts, (caddr_t)arg,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota sizeof (ssp->volts), mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCSTATS
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_stats(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t status;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd status = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CBREAK_STATUS,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->sflags.num; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->sflags.status[i] = (int)((status >> i) & 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&ssp->sflags, (caddr_t)arg,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota sizeof (ssp->sflags), mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCTEMP
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_temp(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int idx;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t status_ov;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_temp_t temps;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(&temps, sizeof (temps));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd idx = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->temps.num; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->temps.temp[i] != LOM_TEMP_STATE_NOT_PRESENT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd temps.temp[idx] = ssp->temps.temp[i];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bcopy(ssp->temps.name[i], temps.name[idx],
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (temps.name[idx]));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd temps.warning[idx] = ssp->temps.warning[i];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd temps.shutdown[idx] = ssp->temps.shutdown[i];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd idx++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd temps.num = idx;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bcopy(ssp->temps.name_ov, temps.name_ov, sizeof (temps.name_ov));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd temps.num_ov = ssp->temps.num_ov;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd status_ov = bscv_get8_locked(ssp, chan_general, EBUS_IDX_OTEMP_STATUS,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->temps.num_ov; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.status_ov[i] = (status_ov >> i) & 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&temps, (caddr_t)arg, sizeof (temps),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCCONS
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_cons(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_cbuf_t cbuf;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int datasize;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(&cbuf, sizeof (cbuf));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd datasize = EBUS_IDX1_CONS_BUF_END - EBUS_IDX1_CONS_BUF_START + 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Ensure that we do not overfill cbuf and that it is NUL terminated */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (datasize > (sizeof (cbuf) - 1)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd datasize = sizeof (cbuf) - 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_rep_get8_locked(ssp, chan_general, (uint8_t *)cbuf.lrbuf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE1, (EBUS_IDX1_CONS_BUF_END - datasize + 1)),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd datasize, DDI_DEV_AUTOINCR, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* This is always within the array due to the checks above */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cbuf.lrbuf[datasize] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&cbuf, (caddr_t)arg, sizeof (cbuf),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCEVENTLOG2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_eventlog2(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_eventlog2_t *eventlog2;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int events_recorded;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int level;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t next_offset;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_event_t event;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventlog2 = (lom_eventlog2_t *)kmem_zalloc(sizeof (*eventlog2),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd KM_SLEEP);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * First get number of events and level requested.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyin((caddr_t)arg, (caddr_t)eventlog2,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (lom_eventlog2_t), mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd kmem_free((void *)eventlog2, sizeof (*eventlog2));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * OK we have full private access to the LOM now so loop
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * over the eventlog addr spaces until we get the required
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * number of events.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!bscv_window_setup(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd kmem_free((void *)eventlog2, sizeof (*eventlog2));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Read count, next event ptr MSB,LSB. Note a read of count
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * is necessary to latch values for the next event ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, EBUS_IDX_UNREAD_EVENTS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd next_offset = bscv_get16(ssp, chan_general, EBUS_IDX_LOG_PTR_HI);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'I', "bscv_ioc_eventlog2", "log_ptr_hi 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd next_offset);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd events_recorded = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (events_recorded < eventlog2->num) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Working backwards - read an event at a time.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * next_offset is one event on from where we want to be!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Decrement next_offset and maybe wrap to the end of the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * buffer.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note the unsigned arithmetic, so check values first!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (next_offset <= ssp->eventlog_start) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Wrap to the end of the buffer */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd next_offset = ssp->eventlog_start + ssp->eventlog_size;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'I', "bscv_ioc_eventlog2", "wrapping"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " around to end of buffer; next_offset 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd next_offset);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd next_offset -= sizeof (event);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_eerw(ssp, next_offset, (uint8_t *)&event,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (event), B_FALSE /* read */) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Fault reading data - stop */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'I', "bscv_ioc_eventlog2", "read"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " failure for offset 0x%x", next_offset);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_is_null_event(ssp, &event)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * No more events in this log so give up.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'I', "bscv_ioc_eventlog2", "no more"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " events left at offset 0x%x", next_offset);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Are we interested in this event
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = bscv_level_of_event(&event);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (level <= eventlog2->level) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Arggh why the funny byte ordering 3, 2, 0, 1 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventlog2->code[events_recorded] =
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_event |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_subsys << 8) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_resource << 16) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_detail << 24));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventlog2->time[events_recorded] =
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_data[0] |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_data[1] << 8) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_data[3] << 16) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((unsigned)event.ev_data[2] << 24));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_build_eventstring(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd &event, eventlog2->string[events_recorded],
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventlog2->string[events_recorded] +
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (eventlog2->string[events_recorded]));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd events_recorded++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventlog2->num = events_recorded;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)eventlog2, (caddr_t)arg,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota sizeof (lom_eventlog2_t), mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd kmem_free((void *)eventlog2, sizeof (lom_eventlog2_t));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCINFO2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_info2(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom2_info_t info2;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t csum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(&info2, sizeof (info2));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) strncpy(info2.escape_chars, ssp->escape_chars,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (info2.escape_chars));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.serial_events = ssp->reporting_level | ssp->serial_reporting;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.a3mode = WATCHDOG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.fver = bscv_get8_locked(ssp, chan_general, EBUS_IDX_FW_REV, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd csum = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_HI, &res)
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota << 8;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd csum |= bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_LO, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.fchksum = csum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.prod_rev = bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_MODEL_REV, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < sizeof (info2.prod_id); i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.prod_id[i] = bscv_get8_locked(ssp, chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX_MODEL_ID1 + i, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.serial_config = bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_SER_TIMEOUT, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_CONFIG_MISC, &res) &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CONFIG_MISC_SECURITY_ENABLED) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.serial_config |= LOM_SER_SECURITY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_CONFIG_MISC, &res) &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CONFIG_MISC_AUTO_CONSOLE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.serial_config |= LOM_SER_RETURN;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_WDOG_CTRL, &res) &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_WDOG_BREAK_DISABLE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.serial_config |= LOM_DISABLE_WDOG_BREAK;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.baud_rate = bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_SER_BAUD, &res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.serial_hw_config =
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((int)bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_SER_CHARMODE, &res) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((int)bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_SER_FLOWCTL, &res) << 8) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((int)bscv_get8_locked(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_SER_MODEMTYPE, &res) << 16));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * There is no phone home support on the blade platform. We hardcode
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * FALSE and NUL for config and script respectively.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.phone_home_config = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info2.phone_home_script[0] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->num_fans; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) strcpy(info2.fan_names[i], ssp->fan_names[i]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&info2, (caddr_t)arg, sizeof (info2),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCTEST
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_test(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t test;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t testnum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t testarg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyin((caddr_t)arg, (caddr_t)&test, sizeof (test),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Extract num iterations.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd testarg = (test & 0xff00) >> 8;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd testnum = test & 0xff;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'F', "bscv_ioc_test",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "LOMIOCTEST data 0x%x (test 0x%x, arg 0x%x)",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd test, (EBUS_IDX_SELFTEST0 + testnum), testarg);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (testnum + EBUS_IDX_SELFTEST0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Invalid test */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EINVAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST0: /* power on self-test result */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST1: /* not used currently */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST2: /* not used currently */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST3: /* not used currently */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST4: /* not used currently */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST5: /* not used currently */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST6: /* LED self-test */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_SELFTEST7: /* platform-specific tests */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Run the test */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Stop other things and then run the test */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Then we simply write the argument to the relevant register
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and wait for the return code.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_SELFTEST0 + testnum, testarg);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Get hold of the SunVTS error code */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd test = bscv_retcode(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'F', "bscv_ioc_test",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "LOMIOCTEST status 0x%x, res 0x%x", test, res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&test, (caddr_t)arg, sizeof (test),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCMPROG2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_mprog2(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom2_mprog_t mprog2;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t base_addr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t data_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t eeprom_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyin((caddr_t)arg, (caddr_t)&mprog2, sizeof (mprog2),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note that originally this was accessed as 255 byte pages
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * in address spaces 240-255. We have to emulate this behaviour.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((mprog2.addr_space < 240) || (mprog2.addr_space > 255)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EINVAL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Calculate required data location */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd data_size = 255;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd base_addr = (mprog2.addr_space - 240) * data_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eeprom_size = bscv_get8(ssp, chan_general, EBUS_IDX_EEPROM_SIZE_KB) *
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota 1024;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((base_addr + data_size) > eeprom_size) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'M', "bscv_ioc_mprog2",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Request extends past end of eeprom");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENXIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_general, EBUS_IDX_CMD_RES, EBUS_CMD_UNLOCK1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'M', "bscv_ioc_mprog2", "ML1 Write failed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_general, EBUS_IDX_CMD_RES, EBUS_CMD_UNLOCK2);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'M', "bscv_ioc_mprog2", "ML2 Write failed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_eerw(ssp, base_addr, &mprog2.data[0],
1c42de6d020629af774dd9e9fc81be3f3ed9398egd data_size, B_TRUE /* write */) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Read a probe key to release the lock. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, EBUS_IDX_PROBEAA);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * LOMIOCMREAD2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_ioc_mread2(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom2_mprog_t mprog2;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t base_addr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t data_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t eeprom_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyin((caddr_t)arg, (caddr_t)&mprog2, sizeof (mprog2),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Need to stop the queue and then just read
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the bytes blind to the relevant addresses.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note that originally this was accessed as 255 byte pages
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * in address spaces 240-255. We have to emulate this behaviour.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((mprog2.addr_space < 240) || (mprog2.addr_space > 255)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EINVAL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Calculate required data location */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd data_size = 255;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd base_addr = (mprog2.addr_space - 240) * data_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eeprom_size = bscv_get8(ssp, chan_general, EBUS_IDX_EEPROM_SIZE_KB) *
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota 1024;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((base_addr + data_size) > eeprom_size) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'M', "bscv_ioc_mread2",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Request extends past end of eeprom");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (ENXIO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_eerw(ssp, base_addr, &mprog2.data[0],
1c42de6d020629af774dd9e9fc81be3f3ed9398egd data_size, B_FALSE /* read */) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((res == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ddi_copyout((caddr_t)&mprog2, (caddr_t)arg, sizeof (mprog2),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get_state_changes(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i = STATUS_READ_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t change;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t detail;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (i-- && !ssp->cssp_prog) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Are there any changes to process? */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd change = bscv_get8(ssp, chan_general, EBUS_IDX_STATE_CHNG);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd change &= EBUS_STATE_MASK;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!change)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Clarify the pending change */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd detail = bscv_get8(ssp, chan_general, EBUS_IDX_EVENT_DETAIL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_status(ssp, change, detail);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_get_state_changes",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "loop index %d ssp->cssp_prog 0x%x", i, ssp->cssp_prog);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Event Processing
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_event_daemon
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - Perform periodic lom tasks in a separate thread.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_event_daemon(void *arg)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp = (void *)arg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t do_events;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t do_status;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t do_nodename;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t do_watchdog;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t async_reg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t fault;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd clock_t poll_period = BSC_EVENT_POLL_NORMAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int fault_cnt = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_event_daemon: started");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Acquire task daemon lock. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags |= TASK_ALIVE_FLG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (;;) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((ssp->task_flags & TASK_STOP_FLG) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Stop request seen - terminate */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((ssp->task_flags & TASK_PAUSE_FLG) == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Poll for events reported to the nexus */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Probe and Check faults */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd async_reg = bscv_probe(ssp, chan_general, &fault);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "process event: async_reg 0x%x, fault 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd async_reg, fault);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!fault) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Treat non-fault conditions */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->cssp_prog || ssp->prog_mode_only) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The BSC has become available again.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault_cnt = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cssp_prog = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_attach_common(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (fault_cnt > 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Previous fault has cleared */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_clear_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault_cnt = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "!bscv_event_daemon previous fault "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "cleared.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Previous fault has cleared */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_clear_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Sleep to avoid busy waiting */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_sleep = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd poll_period = BSC_EVENT_POLL_NORMAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (async_reg) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->status_change = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_waiting = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->cssp_prog) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Expect radio silence or error values
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * when the CSSP is upgrading the BSC firmware
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * so throw away any fault indication.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (fault_cnt == BSC_PROBE_FAULT_LIMIT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Count previous faults and maybe fail */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Declare the lom broken */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_set_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd poll_period = BSC_EVENT_POLL_FAULTY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "!bscv_event_daemon had faults probing "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom - marking it as faulty.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Increment fault_cnt to ensure that
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * next time we do not report a message
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * i.e. we drop out of the bottom
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault_cnt = BSC_PROBE_FAULT_LIMIT + 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_sleep = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (fault_cnt < BSC_PROBE_FAULT_LIMIT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd poll_period = BSC_EVENT_POLL_FAULTY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * No recovery messages in this case
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * because there was never a fault
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * message here.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault_cnt = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Getting ready to explode */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault_cnt++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "!bscv_event_daemon had fault 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_sleep = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * we have no platmod hook on Solaris x86 to report
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * a change to the nodename so we keep a copy so
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * we can detect a change and request that the bsc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * be updated when appropriate.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (strcmp(ssp->last_nodename, utsname.nodename) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "utsname.nodename='%s' possible change detected",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd utsname.nodename);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->nodename_change = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) strncpy(ssp->last_nodename, utsname.nodename,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota sizeof (ssp->last_nodename));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* enforce null termination */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->last_nodename[sizeof (ssp->last_nodename) - 1] =
1c42de6d020629af774dd9e9fc81be3f3ed9398egd '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (((ssp->task_flags & TASK_PAUSE_FLG) == 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fault_cnt == 0 && ssp->cssp_prog == B_FALSE &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ssp->event_waiting || ssp->status_change ||
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ssp->nodename_change || ssp->watchdog_change)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd do_events = ssp->event_waiting;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_waiting = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags |= do_events ?
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota TASK_EVENT_PENDING_FLG : 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd do_status = ssp->status_change;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->status_change = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd do_nodename = ssp->nodename_change;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->nodename_change = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd do_watchdog = ssp->watchdog_change;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->watchdog_change) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->watchdog_change = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We must not hold task_mu whilst processing
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * events because this can lead to priority
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inversion and hence our interrupts getting
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * locked out.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (do_events) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_event_process(ssp, do_events);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (do_nodename) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "do_nodename task");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_hostname(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (do_watchdog) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "do_watchdog task");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_watchdog(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Pending status changes are dealt with last because
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * if we see that the BSC is about to be programmed,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * then it will expect us to to quiescent in the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * first second so it can cleanly tear down its comms
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * protocols; this takes ~100 ms.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (do_status) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get_state_changes(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_session_error(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Had fault during event session. We always
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * sleep after one of these because there
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * may be a problem with the lom which stops
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * us doing useful work in the event daemon.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * If we don't sleep then we may livelock.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "had session error - sleeping");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_sleep = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->task_flags & TASK_EVENT_PENDING_FLG) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We have read any events which were
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * pending. Let the consumer continue.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Ignore the race condition with new events
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * arriving - just let the consumer have
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * whatever was pending when they asked.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_active_count++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags &= ~(TASK_EVENT_PENDING_FLG |
1c42de6d020629af774dd9e9fc81be3f3ed9398egd TASK_EVENT_CONSUMER_FLG);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_broadcast(&ssp->task_evnt_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* There was nothing to do - sleep */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_sleep = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->event_sleep) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags |= TASK_SLEEPING_FLG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Sleep until there is something to do */
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni (void) cv_reltimedwait(&ssp->task_cv,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &ssp->task_mu, poll_period, TR_CLOCK_TICK);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags &= ~TASK_SLEEPING_FLG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_sleep = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->task_flags & TASK_EVENT_CONSUMER_FLG) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We are going away so wake up any event consumer.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Pretend that any pending events have been processed.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_active_count += 2;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_broadcast(&ssp->task_evnt_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(!(ssp->task_flags & TASK_EVENT_PENDING_FLG));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags &=
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ~(TASK_STOP_FLG | TASK_ALIVE_FLG | TASK_EVENT_CONSUMER_FLG);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "exiting.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_start_event_daemon
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - Create the event daemon thread.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_start_event_daemon(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_THREAD)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Start the event thread after the queue has started */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) thread_create(NULL, 0, (void (*)())bscv_event_daemon, ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd 0, &p0, TS_RUN, minclsyspri);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress |= BSCV_THREAD;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_stop_event_daemon
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - Attempt to stop the event daemon thread.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS OR DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_stop_event_daemon(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int try;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = DDI_SUCCESS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Wait for task daemon to stop running. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (try = 0;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((ssp->task_flags & TASK_ALIVE_FLG) && try < 10);
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota try++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Signal that the task daemon should stop */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags |= TASK_STOP_FLG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_signal(&ssp->task_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Release task daemon lock. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * TODO - when the driver is modified to support
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * system suspend or if this routine gets called
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * during panic we should use drv_usecwait() rather
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * than delay in those circumstances.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd delay(drv_usectohz(1000000));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->task_flags & TASK_ALIVE_FLG) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = DDI_FAILURE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_pause_event_daemon
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - Attempt to pause the event daemon thread.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS OR DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_pause_event_daemon(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int try;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!(ssp->progress & BSCV_THREAD)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Nothing to do */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (BSCV_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_pause_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Attempting to pause event daemon");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Signal that the task daemon should pause */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags |= TASK_PAUSE_FLG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Wait for task daemon to pause. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (try = 0;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (!(ssp->task_flags & TASK_SLEEPING_FLG) &&
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (ssp->task_flags & TASK_ALIVE_FLG) &&
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota try < 10);
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota try++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Paranoia */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags |= TASK_PAUSE_FLG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_signal(&ssp->task_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Release task daemon lock. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd delay(drv_usectohz(1000000));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((ssp->task_flags & TASK_SLEEPING_FLG) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd !(ssp->task_flags & TASK_ALIVE_FLG)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_pause_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Pause event daemon - success");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (BSCV_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_pause_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Pause event daemon - failed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (BSCV_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_resume_event_daemon
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - Resumethe event daemon thread.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - None.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_resume_event_daemon(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!(ssp->progress & BSCV_THREAD)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Nothing to do */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Allow the task daemon to resume event processing */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->task_flags &= ~TASK_PAUSE_FLG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_signal(&ssp->task_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_pause_event_daemon",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Event daemon resumed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_event_process
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - process (report) events
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - Soft state ptr, process event request
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_event_process(bscv_soft_state_t *ssp, boolean_t do_events)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t currptr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unsigned int count;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Raw values read from the lom */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t evcount;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t logptr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_event_t event;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (do_events) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Read count, next event ptr MSB,LSB. Note a read of count
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * latches values for the next event ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd evcount = bscv_get8(ssp, chan_general, EBUS_IDX_UNREAD_EVENTS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd logptr = bscv_get16(ssp, chan_general, EBUS_IDX_LOG_PTR_HI);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Sanity check the values from the lom */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd count = bscv_event_validate(ssp, logptr, evcount);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (count == -1) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Nothing to do - or badly configured event log.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We really do not want to touch the lom in this
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * case because any data that we access may be bad!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This differs from zero because if we have zero
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * to read the lom probably things that unread is
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * non-zero and we want that to be set to zero!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Signal event fault to make the thread wait
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * before attempting to re-read the log.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_sleep = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto logdone;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->event_fault_reported) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Clear down any old status - things are fixed */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_NOTE, "Event pointer fault recovered.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_fault_reported = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Compute the first entry that we need to read. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd currptr = logptr - ssp->eventlog_start;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd currptr += ssp->eventlog_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd currptr -= (count * sizeof (event));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd currptr %= ssp->eventlog_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd currptr += ssp->eventlog_start;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_event_process",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "processing %d events from 0x%x in 0x%x:0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd count, currptr,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eventlog_start,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eventlog_start + ssp->eventlog_size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (; count > 0; count--) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Ensure window is positioned correctly */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_eerw(ssp, currptr, (uint8_t *)&event,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (event), B_FALSE /* read */) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Fault reading data - stop */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_event_process_one(ssp, &event);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_sysevent(ssp, &event);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd currptr += sizeof (event);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (currptr >= ssp->eventlog_start +
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->eventlog_size) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd currptr = ssp->eventlog_start;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Clear event count - write the evcount value to remove that
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * many from the unread total.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Adjust the value to reflect how many we have left to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * read just in case we had a failure reading events.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (count == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*EMPTY*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(logptr == currptr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (count > evcount) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd evcount = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd evcount -= count;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_general, EBUS_IDX_UNREAD_EVENTS, evcount);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Remember where we were for next time */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->oldeeptr = currptr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->oldeeptr_valid = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egdlogdone:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_event_validate
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - validate the event data supplied by the lom and determine
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * how many (if any) events to read.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This function performs complex checks to ensure that
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * events are not lost due to lom resets or host resets.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * A combination of lom reset and host reset (i.e. power fail)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * may cause some events to not be reported.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - Soft state ptr, next event pointer, number of unread events.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - the number of events to read. -1 on error.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * zero is a valid value because it forces the loms unread
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * count to be cleared.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_event_validate(bscv_soft_state_t *ssp, uint32_t newptr, uint8_t unread)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t oldptr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unsigned int count;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!bscv_window_setup(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Problem with lom eeprom setup we cannot do anything */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (-1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Sanity check the event pointers */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((newptr < ssp->eventlog_start) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (newptr >= (ssp->eventlog_start + ssp->eventlog_size))) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->event_fault_reported) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "Event pointer out of range. "
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota "Cannot read events.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->event_fault_reported = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (-1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd oldptr = ssp->oldeeptr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Now sanity check log pointer against count */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (newptr < oldptr) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Must have wrapped add eventlog_size to get the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * correct relative values - this makes the checks
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * below work!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd newptr += ssp->eventlog_size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->oldeeptr_valid) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* We have just started up - we have to trust lom */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd count = unread;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((unread == 0) && (newptr == oldptr)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Nothing to do - we were just polling */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (-1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (oldptr + (unread * sizeof (lom_event_t)) == newptr) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Ok - got as many events as we expected */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd count = unread;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (oldptr + (unread * sizeof (lom_event_t)) > newptr) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Errrm more messages than there should have been.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Possible causes:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 1. the event log has filled - we have been
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * away for a long time
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 2. software bug in lom or driver.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * 3. something that I haven't thought of!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Always warn about this we should really never
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * see it!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd count = (newptr - oldptr) / sizeof (lom_event_t);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_event_process",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_event_process: lom reported "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "more events (%d) than expected (%d).",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unread, count);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT, "only processing %d events", count);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Less messages - perhaps the lom has been reset */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd count = (newptr - oldptr) / sizeof (lom_event_t);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_event_process",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom reported less events (%d) than expected (%d)"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - the lom may have been reset",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unread, count);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Whatever happens only read a maximum of 255 entries */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((count >= 0xff)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_event_process: too many events (%d) to "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "process - some may have been lost", count);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd count = 0xff;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (count);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_event_process_one
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - reports on state changes to the host.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_event_process_one(bscv_soft_state_t *ssp, lom_event_t *event)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int level;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char eventstr[100];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int msg_type = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_is_null_event(ssp, event)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Cleared entry - do not report it */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = bscv_level_of_event(event);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (level) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd msg_type = CE_NOTE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_LEVEL_FATAL:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_LEVEL_FAULT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd msg_type = CE_WARN;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_build_eventstring(ssp, event, eventstr, eventstr +
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (eventstr));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (level <= ssp->reporting_level) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The message is important enough to be shown on the console
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * as well as the log.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(msg_type, "%s", eventstr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The message goes only to the log.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(msg_type, "!%s", eventstr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * time formats
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The BSC represents times as seconds since epoch 1970. Currently it gives
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * us 32 bits, unsigned. In the future this might change to a 64-bit count,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * to allow a greater range.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Timestamp values below BSC_TIME_SANITY do not represent an absolute time,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * but instead represent an offset from the last reset. This must be
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * borne in mind by output routines.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdtypedef uint32_t bsctime_t;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#define BSC_TIME_SANITY 1000000000
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * render a formatted time for display
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic size_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_event_snprintgmttime(char *buf, size_t bufsz, todinfo_t t)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int year;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* tod_year is base 1900 so this code needs to adjust */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd year = 1900 + t.tod_year;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (snprintf(buf, bufsz, "%04d-%02d-%02d %02d:%02d:%02dZ",
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota year, t.tod_month, t.tod_day, t.tod_hour,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota t.tod_min, t.tod_sec));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_build_eventstring
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - reports on state changes to the host.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_build_eventstring(bscv_soft_state_t *ssp, lom_event_t *event,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *buf, char *bufend)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t subsystem;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t eventtype;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bsctime_t bsctm;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'S', "bscv_build_eventstring", "event %2x%2x%2x%2x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_subsys, event->ev_event,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource, event->ev_detail);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'S', "bscv_build_eventstring", "time %2x%2x%2x%2x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_data[0], event->ev_data[1],
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_data[2], event->ev_data[3]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We accept bad subsystems and event type codes here.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The code decodes as much as possible and then produces
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * suitable output.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd subsystem = EVENT_DECODE_SUBSYS(event->ev_subsys);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventtype = event->ev_event;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* time */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bsctm = (((uint32_t)event->ev_data[0]) << 24) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (((uint32_t)event->ev_data[1]) << 16) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (((uint32_t)event->ev_data[2]) << 8) |
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ((uint32_t)event->ev_data[3]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bsctm < BSC_TIME_SANITY) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* offset */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend-buf, "+P%dd%02dh%02dm%02ds",
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (int)(bsctm/86400), (int)(bsctm/3600%24),
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (int)(bsctm/60%60), (int)(bsctm%60));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* absolute time */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&tod_lock);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += bscv_event_snprintgmttime(buf, bufend-buf,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota utc_to_tod(bsctm));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&tod_lock);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend-buf, " ");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* subsysp */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (subsystem <
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (sizeof (eventSubsysStrings)/sizeof (*eventSubsysStrings))) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, "%s",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventSubsysStrings[subsystem]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "unknown subsystem %d ", subsystem);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* resource */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (subsystem) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_ALARM:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_TEMP:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_OVERTEMP:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_FAN:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_SUPPLY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_BREAKER:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_PSU:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, "%d ", event->ev_resource);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_LED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, "%s ", bscv_get_label(
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->led_names, MAX_LED_ID, event->ev_resource - 1));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* fatal */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (event->ev_subsys & EVENT_MASK_FAULT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (event->ev_subsys & EVENT_MASK_FATAL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, "FATAL FAULT: ");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, "FAULT: ");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* eventp */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (eventtype <
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (sizeof (eventTypeStrings)/sizeof (*eventTypeStrings))) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, "%s",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd eventTypeStrings[eventtype]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "unknown event 0x%02x%02x%02x%02x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_subsys, event->ev_event,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource, event->ev_detail);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* detail */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (subsystem) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_TEMP:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((eventtype != EVENT_RECOVERED) &&
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota eventtype != EVENT_DEVICE_INACCESSIBLE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " - %d degC",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (int8_t)event->ev_detail);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_FAN:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (eventtype == EVENT_FAILED) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " %d%%", event->ev_detail);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_LOM:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (eventtype) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_FLASH_DOWNLOAD:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ": v%d.%d to v%d.%d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (event->ev_resource >> 4),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (event->ev_resource & 0x0f),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (event->ev_detail >> 4),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (event->ev_detail & 0x0f));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_WATCHDOG_TRIGGER:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_detail ? "- soft" : " - hard");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_UNEXPECTED_RESET:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (event->ev_detail &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd LOM_UNEXPECTEDRESET_MASK_BADTRAP) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - unclaimed exception 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_detail &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ~LOM_UNEXPECTEDRESET_MASK_BADTRAP);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_RESET:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_detail) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_RESET_DETAIL_BYUSER:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " by user");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_RESET_DETAIL_REPROGRAMMING:
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " after flash download");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - unknown reason");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_LED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_detail) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_OFF:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, ": OFF");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_ON_STEADY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, ": ON");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_ON_FLASHING:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_ON_SLOWFLASH:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, ": BLINKING");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_INACCESSIBLE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, ": inaccessible");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_STANDBY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, ": standby");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case LOM_LED_STATE_NOT_PRESENT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, ": not present");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, ": 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_USER:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (eventtype) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_USER_ADDED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_USER_REMOVED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_USER_PERMSCHANGED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_USER_LOGIN:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_USER_PASSWORD_CHANGE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_USER_LOGINFAIL:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_USER_LOGOUT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_PSU:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (event->ev_detail & LOM_PSU_NOACCESS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " - inaccessible");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((event->ev_detail & LOM_PSU_STATUS_MASK)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd == LOM_PSU_STATUS_MASK) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " - OK");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " -");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * If both inputs are seen to have failed then simply
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * indicate that the PSU input has failed
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!(event->ev_detail &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (LOM_PSU_INPUT_A_OK | LOM_PSU_INPUT_B_OK))) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " Input");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* At least one input is ok */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!(event->ev_detail & LOM_PSU_INPUT_A_OK)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " InA");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!(event->ev_detail & LOM_PSU_INPUT_B_OK)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " InB");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Only flag an output error if an input is
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * still present
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!(event->ev_detail & LOM_PSU_OUTPUT_OK)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " Output");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " failed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_NONE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (eventtype == EVENT_FAULT_LED) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_detail) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case 0:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " - ON");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case 255:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " - OFF");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - %dHz", event->ev_detail);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EVENT_SUBSYS_HOST:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (eventtype == EVENT_BOOTMODE_CHANGE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_detail &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ~EBUS_BOOTMODE_FORCE_CONSOLE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_BOOTMODE_FORCE_NOBOOT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - no boot");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_BOOTMODE_RESET_DEFAULT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - reset defaults");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_BOOTMODE_FULLDIAG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - full diag");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_BOOTMODE_SKIPDIAG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - skip diag");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (eventtype == EVENT_SCC_STATUS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_detail) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case 0:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - inserted");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case 1:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " - removed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* shutd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (event->ev_subsys & EVENT_MASK_SHUTDOWN_REQD) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, " - shutdown req'd");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf += snprintf(buf, bufend - buf, "\n");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (buf >= bufend) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Ensure newline at end of string */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bufend[-2] = '\n';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bufend[-1] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef DEBUG
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_build_eventstring: buffer too small!");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* DEBUG */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_level_of_event
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - This routine determines which level an event should be
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * reported at.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - lom event structure pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - event level.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_level_of_event(lom_event_t *event)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int level;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This is the same criteria that the firmware uses except we
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * log the fault led on as being EVENT_LEVEL_FAULT
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (EVENT_DECODE_SUBSYS(event->ev_subsys) == EVENT_SUBSYS_USER) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_USER;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((EVENT_DECODE_SUBSYS(event->ev_subsys) ==
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EVENT_SUBSYS_ALARM) && (event->ev_event == EVENT_STATE_ON)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_FAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((EVENT_DECODE_SUBSYS(event->ev_subsys) ==
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EVENT_SUBSYS_NONE) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (event->ev_event == EVENT_FAULT_LED) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (event->ev_detail != 0xff)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_FAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((EVENT_DECODE_SUBSYS(event->ev_subsys) ==
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EVENT_SUBSYS_LOM) && event->ev_event == EVENT_TIME_REFERENCE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_NOTICE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (event->ev_event == EVENT_RECOVERED) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * All recovery messages need to be reported to the console
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * because during boot, the faults which occurred whilst
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Solaris was not running are relayed to the console. There
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * is a case whereby a fatal fault (eg. over temp) could
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * have occurred and then recovered. The recovery condition
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * needs to be reported so the user doesn't think that the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * failure (over temp) is still present.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_FAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (EVENT_DECODE_FAULT(event->ev_subsys) == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* None of FAULT, FATAL or SHUTDOWN REQD are set */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_NOTICE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (EVENT_DECODE_FAULT(event->ev_subsys) == EVENT_MASK_FAULT) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Only FAULT set i.e not FATAL or SHUTDOWN REQD */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_FAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd level = EVENT_LEVEL_FATAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (level);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_status
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - This routine is called when any change in the LOMlite2 status
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * is indicated by the status registers.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - LOM soft state structure pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_status(bscv_soft_state_t *ssp, uint8_t state_chng, uint8_t dev_no)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int8_t temp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t fanspeed;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_status", "state_chng 0x%x dev_no 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd state_chng, dev_no);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The device that has changed is given by the state change
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * register and the event detail register so react
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * accordingly.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (state_chng == EBUS_STATE_NOTIFY) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The BSC is indicating a self state change
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (dev_no == EBUS_DETAIL_FLASH) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cssp_prog = B_TRUE;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_status",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "ssp->cssp_prog changed to 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cssp_prog);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * It takes the BSC at least 100 ms to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * clear down the comms protocol.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We back-off from talking to the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * BSC during this period.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd delay(BSC_EVENT_POLL_NORMAL);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_status",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "completed delay");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (dev_no == EBUS_DETAIL_RESET) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The bsc has reset
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_status",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "BSC reset occured, re-synching");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_attach_common(ssp);
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'D', "bscv_status",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "completed attach_common");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((state_chng & EBUS_STATE_FAN) && ((dev_no - 1) < MAX_FANS)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fanspeed = bscv_get8(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_FAN1_SPEED + dev_no - 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Only remember fanspeeds which are real values or
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * NOT PRESENT values.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((fanspeed <= LOM_FAN_MAX_SPEED) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (fanspeed == LOM_FAN_NOT_PRESENT)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->fanspeed[dev_no - 1] = fanspeed;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((state_chng & EBUS_STATE_PSU) && ((dev_no - 1) < MAX_PSUS)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_PSU1_STAT + dev_no - 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (state_chng & EBUS_STATE_GP) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, EBUS_IDX_GPIP);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (state_chng & EBUS_STATE_CB) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, EBUS_IDX_CBREAK_STATUS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((state_chng & EBUS_STATE_TEMPERATURE) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((dev_no - 1) < MAX_TEMPS)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd temp = bscv_get8(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_TEMP1 + dev_no - 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Only remember temperatures which are real values or
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * a NOT PRESENT value.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((temp <= LOM_TEMP_MAX_VALUE) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (temp == LOM_TEMP_STATE_NOT_PRESENT)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.temp[dev_no - 1] = temp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (state_chng & EBUS_STATE_RAIL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, EBUS_IDX_SUPPLY_LO);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, EBUS_IDX_SUPPLY_HI);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdchar *
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get_label(char labels[][MAX_LOM2_NAME_STR], int limit, int index)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (labels == NULL)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return ("");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (limit < 0 || index < 0 || index > limit)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return ("-");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (labels[index]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_generic_sysevent(bscv_soft_state_t *ssp, char *class, char *subclass,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *fru_id, char *res_id, int32_t fru_state, char *msg)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int rv;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_t *attr_list;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent", "%s/%s:(%s,%s,%d) %s",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd class, subclass, fru_id, res_id, fru_state, msg);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, KM_SLEEP)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nvlist alloc failure");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nvlist_add_uint32(attr_list, ENV_VERSION, 1)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nvlist ENV_VERSION failure");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_free(attr_list);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nvlist_add_string(attr_list, ENV_FRU_ID, fru_id)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nvlist ENV_FRU_ID failure");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_free(attr_list);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nvlist_add_string(attr_list, ENV_FRU_RESOURCE_ID, res_id)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nvlist ENV_FRU_RESOURCE_ID failure");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_free(attr_list);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nvlist_add_string(attr_list, ENV_FRU_DEVICE, ENV_RESERVED_ATTR)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nvlist ENV_FRU_DEVICE failure");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_free(attr_list);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nvlist_add_int32(attr_list, ENV_FRU_STATE, fru_state)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nvlist ENV_FRU_STATE failure");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_free(attr_list);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nvlist_add_string(attr_list, ENV_MSG, msg)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nvlist ENV_MSG failure");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_free(attr_list);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd rv = ddi_log_sysevent(ssp->dip, DDI_VENDOR_SUNW, class,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd subclass, attr_list, NULL, DDI_SLEEP);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (rv == DDI_SUCCESS) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_generic_sysevent", "sent sysevent");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!cannot deliver sysevent");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nvlist_free(attr_list);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_sysevent
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - send out a sysevent on the given change if needed
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state pointer, event to report
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_sysevent(bscv_soft_state_t *ssp, lom_event_t *event)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *class = NULL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *subclass = NULL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *fru_id = "Blade"; /* The blade is only one FRU */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *res_id;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int32_t fru_state = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_sysevent", "processing event");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(event != NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Map ev_subsys to sysevent class/sub-class */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (EVENT_DECODE_SUBSYS(event->ev_subsys)) {
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_NONE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_ALARM:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_TEMP:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd class = EC_ENV, subclass = ESC_ENV_TEMP;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res_id = bscv_get_label(ssp->temps.name, ssp->temps.num,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource - 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_event) {
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SEVERE_OVERHEAT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_FAILED;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_OVERHEAT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_WARNING;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_NO_OVERHEAT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_OK;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_OVERTEMP:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_FAN:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd class = EC_ENV, subclass = ESC_ENV_FAN;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res_id = bscv_get_label(ssp->fan_names, ssp->num_fans,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource - 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_event) {
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_FAILED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_FAILED;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_RECOVERED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_OK;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_SUPPLY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd class = EC_ENV, subclass = ESC_ENV_POWER;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res_id = bscv_get_label(ssp->sflags.name, ssp->sflags.num,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource - 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_event) {
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_FAILED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_FAILED;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_RECOVERED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_OK;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_BREAKER:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_PSU:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_USER:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_PHONEHOME:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_LOM:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_HOST:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_EVENTLOG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_EXTRA:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case EVENT_SUBSYS_LED:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (event->ev_event != EVENT_FAULT_LED &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_event != EVENT_STATE_CHANGE)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * There are 3 LEDs : Power, Service, Ready-to-Remove on a
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * JBOS blade. We'll never report the Power since Solaris
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * won't be running when it is _switched_ ON. Ready-to-Remove
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * will only be lit when we're powered down which also means
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Solaris won't be running. We don't want to report it
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * during system testing / Sun VTS exercising the LEDs.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Therefore, we only report the Service Required LED.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd class = EC_ENV, subclass = ESC_ENV_LED;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res_id = bscv_get_label(ssp->led_names, MAX_LED_ID,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd event->ev_resource - 1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (event->ev_detail) {
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case LOM_LED_STATE_ON_STEADY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_LED_ON;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case LOM_LED_STATE_ON_FLASHING:
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case LOM_LED_STATE_ON_SLOWFLASH:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_LED_BLINKING;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case LOM_LED_STATE_OFF:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_LED_OFF;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case LOM_LED_STATE_INACCESSIBLE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_LED_INACCESSIBLE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case LOM_LED_STATE_STANDBY:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_LED_STANDBY;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota case LOM_LED_STATE_NOT_PRESENT:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_LED_NOT_PRESENT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fru_state = ENV_LED_INACCESSIBLE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota default :
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (class == NULL || subclass == NULL) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'E', "bscv_sysevent", "class/subclass NULL");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_generic_sysevent(ssp, class, subclass, fru_id, res_id, fru_state,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ENV_RESERVED_ATTR);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Firmware download (programming)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_prog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - LOMlite2 flash programming code.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_prog_image - download a complete image to the lom.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_prog_receive_image - receive data to build up a
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * complete image.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_prog_stop_lom - pause the event daemon and prepare
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * lom for firmware upgrade.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_prog_start_lom - reinit the driver/lom after upgrade
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and restart the event daemon
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state pointer, arg ptr, ioctl mode
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - status
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_prog(bscv_soft_state_t *ssp, intptr_t arg, int mode)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_prog_t *prog;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We will get repeatedly called with bits of data first for
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * loader, then for main image.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog = (lom_prog_t *)kmem_alloc(sizeof (lom_prog_t), KM_SLEEP);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyin((caddr_t)arg, (caddr_t)prog, sizeof (*prog),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd kmem_free((void *)prog, sizeof (*prog));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "index 0x%x size 0x%x", prog->index, prog->size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->prog_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (prog->size == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (prog->index == 2) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This is the initial request for the chip type so we
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * know what we are programming.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The type will have been read in at init so just
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * return it in data[0].
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog->data[0] = bscv_get8_cached(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX_CPU_IDENT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ddi_copyout((caddr_t)prog, (caddr_t)arg,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (lom_prog_t), mode) < 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EFAULT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (prog->index == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_prog_stop_lom(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (prog->index == 1) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_prog_start_lom(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EINVAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->image == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image = (uint8_t *)kmem_zalloc(
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota BSC_IMAGE_MAX_SIZE, KM_SLEEP);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_prog_receive_image(ssp, prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image, BSC_IMAGE_MAX_SIZE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->prog_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd kmem_free((void *)prog, sizeof (lom_prog_t));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_check_loader_config(bscv_soft_state_t *ssp, boolean_t is_image2)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_check_loader_config",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "loader_running %d, is_image2 %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->loader_running, is_image2);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * loader_running TRUE means that we have told the microcontroller to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * JUMP into the loader code which has been downloaded into its RAM.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * At this point its an error to try and download another loader. We
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * should be downloading the actual image at this point.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Conversely, it is an error to download an image when the loader is
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * not already downloaded and the microcontroller hasn't JUMPed into it.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * is_image2 TRUE means the image is being downloaded.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * is_image2 FALSE means the loader is being downloaded.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->loader_running && !is_image2) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "Attempt to download loader image "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "with loader image already active");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT, "This maybe an attempt to restart a "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "failed firmware download - ignoring download attempt");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (!ssp->loader_running && is_image2) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "Attempt to download firmware image "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "without loader image active");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint32_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_get_pagesize(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t pagesize;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pagesize = bscv_get32(ssp, chan_prog,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PAGE0));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_get_pagesize", "pagesize 0x%x", pagesize);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (pagesize);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Sets the pagesize, returning the old value.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint32_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_set_pagesize(bscv_soft_state_t *ssp, uint32_t pagesize)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t old_pagesize;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd old_pagesize = bscv_get_pagesize(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The microcontroller remembers this value until until someone
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * changes it.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put32(ssp, chan_prog,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PSIZ0), pagesize);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (old_pagesize);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_enter_programming_mode(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_prog,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR),
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_PROGRAM_PCR_PRGMODE_ON);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get8(ssp, chan_prog, BSCVA(EBUS_CMD_SPACE_PROGRAM,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_PROGRAM_PCSR));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_leave_programming_mode(bscv_soft_state_t *ssp, boolean_t with_jmp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t reg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (with_jmp) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd reg = EBUS_PROGRAM_PCR_PROGOFF_JUMPTOADDR;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_leave_programming_mode",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "jumptoaddr");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd reg = EBUS_PROGRAM_PCR_PRGMODE_OFF;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_leave_programming_mode",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "prgmode_off");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_prog,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR), reg);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_set_jump_to_addr(bscv_soft_state_t *ssp, uint32_t loadaddr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put32(ssp, chan_prog,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0), loadaddr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_set_jump_to_addr",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "set jump to loadaddr 0x%x", loadaddr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_erase_once(bscv_soft_state_t *ssp, uint32_t loadaddr, uint32_t image_size)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * write PADR, PSIZ to define area to be erased
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We do not send erase for zero size because the current
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * downloader gets this wrong
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * start at 0
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_erase_once", "sending erase command");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put32(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd loadaddr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* set PSIZ to full size of image to be programmed */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put32(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PSIZ0),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd image_size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* write ERASE to PCSR */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_PROGRAM_PCR_ERASE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* read PCSR to check status */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get8(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_do_erase(bscv_soft_state_t *ssp, uint32_t loadaddr, uint32_t image_size,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t is_image2)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int retryable = BSC_ERASE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (retryable--) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_erase_once(ssp, loadaddr, image_size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (PSR_SUCCESS(retval))
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd else
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "erase error 0x%x, attempt %d"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ", base 0x%x, size 0x%x, %s image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval, BSC_ERASE_RETRY_LIMIT - retryable,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd loadaddr, image_size,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd is_image2 ? "main" : "loader");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_set_page(bscv_soft_state_t *ssp, uint32_t addr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int retryable = BSC_PAGE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (retryable--) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Write the page address and read it back for confirmation.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put32(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get32(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (retval == addr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "programmming error, attempt %d, "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "set page 0x%x, read back 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSC_PAGE_RETRY_LIMIT - retryable,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr, retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return ((addr == retval) ? EBUS_PROGRAM_PSR_SUCCESS :
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_PROGRAM_PSR_INVALID_OPERATION);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_do_page_data_once(bscv_soft_state_t *ssp, uint32_t index,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t image_size, uint32_t pagesize, uint8_t *imagep,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t *calcd_chksum)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t chksum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'P', "bscv_do_page_data_once", "index 0x%x", index);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* write PSIZ bytes to PDAT */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (index + pagesize < image_size) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_rep_rw8(ssp, chan_prog, imagep + index,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_DATA),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pagesize, DDI_DEV_NO_AUTOINCR, B_TRUE /* write */);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size = pagesize;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'P', "bscv_do_page_once",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Sending last block, last 0x%x bytes",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (image_size % pagesize));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size = (image_size - index);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_rep_rw8(ssp, chan_prog, imagep + index,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_DATA),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size, DDI_DEV_NO_AUTOINCR, B_TRUE /* write */);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Now pad the rest of the page with zeros */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = size; i < pagesize; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_PROGRAM_DATA),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd 0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* write the checksum to PCSM */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chksum = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < size; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chksum = ((chksum << 3) | (chksum >> 13)) ^
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota *(imagep + index + i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Cope with non-pagesize sized bufers */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (; i < pagesize; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chksum = ((chksum << 3) | (chksum >> 13)) ^ 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put16(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSM0), chksum);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_PROGRAM_PCR_PROGRAM);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_get8(ssp, chan_prog,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *calcd_chksum = chksum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t bscv_do_page(bscv_soft_state_t *ssp, uint32_t loadaddr,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t index, uint32_t image_size, uint32_t pagesize, uint8_t *imagep,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t is_image2)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int retryable = BSC_PAGE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t checksum;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'P', "bscv_do_page", "index 0x%x", index);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (retryable--) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Set the page address (with retries). If this is not
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * successful, then there is no point carrying on and sending
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the page's data since that could cause random memory
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * corruption in the microcontroller.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_set_page(ssp, loadaddr + index);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!PSR_SUCCESS(retval)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "programming error 0x%x, "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "could not setup page address 0x%x, %s image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval, loadaddr + index,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd is_image2 ? "main" : "loader");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Send down the data for the page
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'P', "bscv_do_page", "sending data for page");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_do_page_data_once(ssp, index, image_size,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pagesize, imagep, &checksum);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (PSR_SUCCESS(retval))
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd else
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "programming error 0x%x,"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " attempt %d, index 0x%x, checksum 0x%x, %s image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval, BSC_PAGE_RETRY_LIMIT - retryable,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd index, checksum, is_image2 ? "main" : "loader");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_do_page", "Returning 0x%x for index 0x%x,"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " checksum 0x%x, %s image", retval, index, checksum,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd is_image2 ? "main" : "loader");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_do_pages(bscv_soft_state_t *ssp, uint32_t loadaddr, uint32_t image_size,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t pagesize, uint8_t *imagep, boolean_t is_image2)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t index;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'P', "bscv_do_pages", "entered");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (index = 0; index < image_size; index += pagesize) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_do_page(ssp, loadaddr, index, image_size,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota pagesize, imagep, is_image2);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || !PSR_SUCCESS(retval)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_do_pages",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Failed to program lom (status 0x%x)", retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_prog_image(bscv_soft_state_t *ssp, boolean_t is_image2,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t *imagep, int image_size, uint32_t loadaddr)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint32_t pagesize;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog_image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "image 0x%x, imagep %p, size 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd is_image2 ? 2 : 1, imagep, image_size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!bscv_check_loader_config(ssp, is_image2))
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Return no error to allow userland to continue on with
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * downloading the image.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pagesize = bscv_get_pagesize(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_enter_programming_mode(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || !PSR_PROG(retval)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "lom: Failed to enter program mode, error 0x%x"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ", %s image", retval, is_image2 ? "main" : "loader");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto BSCV_PROG_IMAGE_END;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog_image", "entered programming mode");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Only issue an erase if we are downloading the image. The loader
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * does not need this step.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (is_image2 && (image_size != 0)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_do_erase(ssp, loadaddr, image_size, is_image2);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || !PSR_SUCCESS(retval)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom: Erase failed during programming, status 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto BSCV_PROG_IMAGE_END;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog_image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "erase complete - programming...");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_set_pagesize(ssp, pagesize);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = bscv_do_pages(ssp, loadaddr, image_size, pagesize, imagep,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota is_image2);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp) || !PSR_SUCCESS(retval)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog_image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Failed to program lom (status 0x%x)", retval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto BSCV_PROG_IMAGE_END;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdBSCV_PROG_IMAGE_END:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (res == 0 && !is_image2) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We've downloaded the loader successfully. Now make the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * microcontroller jump to it.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_set_jump_to_addr(ssp, loadaddr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->loader_running = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_leave_programming_mode(ssp, B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We've just downloaded either the loader which failed, or
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the image (which may or may not have been successful).
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_set_jump_to_addr(ssp, 0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (res != 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog_image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "got error 0x%x - leaving programming mode",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "programming error 0x%x, %s image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res, is_image2 ? "main" : "loader");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog_image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "programming complete - leaving programming mode");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_leave_programming_mode(ssp, B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->loader_running = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_prog_receive_image(bscv_soft_state_t *ssp, lom_prog_t *prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t *imagep, int max_size)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint_t size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int32_t loadaddr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_prog_data_t *prog_data;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((prog->index & 0x7FFF) != ssp->prog_index) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'U', "bscv_prog_receive_image",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Got wrong buffer 0x%x, expected 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog->index & 0x7fff, ssp->prog_index);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EINVAL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We want to get the whole image and then do the download.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * It is assumed the device is now in programming mode.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((prog->index & 0x7fff) == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Starting a new image */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image_ptr = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((ssp->image_ptr + prog->size) > max_size) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom image exceeded maximum size: got 0x%x, maximum 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (ssp->image_ptr + prog->size), max_size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EFAULT);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bcopy(prog->data, &imagep[ssp->image_ptr], prog->size);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image_ptr += prog->size;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_index++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (prog->index & 0x8000) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * OK we have the whole image so synch up and start download.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog_data = (lom_prog_data_t *)imagep;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (prog_data->header.magic != PROG_MAGIC) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Old style programming data */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Take care image may not fill all of structure */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* sign extend loadaddr from 16 to 32 bits */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd loadaddr = (int16_t)((uint16_t)((imagep[2] << 8) +
1c42de6d020629af774dd9e9fc81be3f3ed9398egd imagep[3]));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size = (imagep[0] << 8) + imagep[1];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (size != (ssp->image_ptr - 4)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "Image size mismatch:"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " expected 0x%x, got 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size, (ssp->image_ptr - 1));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_prog_image(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image2_processing,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd imagep + 4, ssp->image_ptr - 4, loadaddr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Done the loading so set the flag to say we are doing
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the other image.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image2_processing = !ssp->image2_processing;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if ((ssp->image_ptr < sizeof (*prog_data)) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (prog_data->platform.bscv.size !=
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (ssp->image_ptr - sizeof (*prog_data)))) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Image too small for new style image */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "image too small");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EINVAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* New style programming image */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (prog_data->platmagic) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case PROG_PLAT_BSCV_IMAGE:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_prog_image(ssp, B_TRUE,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd imagep + sizeof (*prog_data),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog_data->platform.bscv.size,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog_data->platform.bscv.loadaddr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image2_processing = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case PROG_PLAT_BSCV_LOADER:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = bscv_prog_image(ssp, B_FALSE,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd imagep + sizeof (*prog_data),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog_data->platform.bscv.size,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog_data->platform.bscv.loadaddr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image2_processing = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "unknown platmagic 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd prog_data->platmagic);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EINVAL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_index = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image_ptr = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_prog_stop_lom(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->programming) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Already programming - this may be a retry of a failed
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * programming attempt or just a software error!
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd goto queue_stopped;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_pause_event_daemon(ssp) == BSCV_FAILURE) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'Q', "bscv_prog_stop_lom",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "failed to pause event daemon thread");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EAGAIN);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->programming = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdqueue_stopped:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_index = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image2_processing = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_prog_start_lom(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int res = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->programming) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Not programming so this is not a valid command */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (EINVAL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->image != NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd kmem_free((void *)ssp->image, BSC_IMAGE_MAX_SIZE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->image = NULL;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * OK we are out of reset now so:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Probe the firmware and set everything up.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Explicit clear fault because things may have been mended now */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_clear_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->loader_running) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "Firmware upgrade failed to exit loader - "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "performing forced exit");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Must try to restart the lom here. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Ensure prog mode entry to enable PRGMODE_OFF */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_PROGRAM_PCR_PRGMODE_ON);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_prog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_PROGRAM_PCR_PRGMODE_OFF);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->loader_running = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* give the lom chance to recover */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd delay(drv_usectohz(5000000)); /* 5 seconds */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->programming = B_FALSE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_attach_common(ssp) == DDI_FAILURE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd res = EIO;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->prog_mode_only) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Start the event thread after the queue has started
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Not sure if this is entirely correct because
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the other code at the end of bscv_attach()
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * does not get run here.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_start_event_daemon(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_resume_event_daemon(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (res);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Attach processing
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * *********************************************************************
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_attach_common
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - this routine co-ordinates the initialisation of the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * driver both at attach time and after firmware programming.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * sequence - bscv_setup_capability - read LOMlite2 capabilities
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_probe_check - test comms and setup register cache
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_setup_hostname - sync stored name in lom with nodename.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_setup_static_info - read device names etc.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bscv_setup_events - start event daemon etc.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - device information structure, DDI_ATTACH command
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS or DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_attach_common(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_attach_common:", "");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Set the threshold for reporting messages to the console to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Warnings or higher.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->reporting_level = 2;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * When the system is not running the Operating System, make
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the microcontroller print event messages straight onto the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * console.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->serial_reporting = LOM_SER_EVENTS_DEF;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Setup capabilities */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_capability(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_probe_check(ssp) == DDI_FAILURE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "BSC chip not responding");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We want lom -G to talk to this driver upon broken firmware
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * so we prematurely return success here.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_hostname(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_static_info(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_events(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_inform_bsc(ssp, BSC_INFORM_ONLINE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Watchdog configuration and CPU signatures are sent asynchronously
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * with respect to attach so only inform the BSC if we've already
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * sent the data in the past.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_WDOG_CFG)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setup_watchdog(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_SIG_SENT)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_write_sig(ssp, ssp->last_sig);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_cleanup
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - routine that does the necessary tidying up if the attach
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * request fails or the driver is to be detached.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * If the event thread has been started we may fail to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * stop it (because it is busy) so we fail the cleanup
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and hence the detach. All other calls to bscv_cleanup
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * are done before the event daemon is started.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state structure address.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS or DDI_FAILURE.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_cleanup(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t bits2set;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t bits2clear;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd instance = ssp->instance;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_LOCKS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_THREAD) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_stop_event_daemon(ssp) == DDI_FAILURE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Fail the cleanup - may be able to cleanup later */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_LOCKS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_NODES) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_remove_minor_node(ssp->dip, NULL);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_MAPPED_REGS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * switch back on serial event reporting - cover all configs.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2set = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2clear = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->serial_reporting == LOM_SER_EVENTS_ON) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2clear |= EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->serial_reporting == LOM_SER_EVENTS_OFF) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2set |= EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->serial_reporting == LOM_SER_EVENTS_DEF) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2clear |= EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setclear8_volatile(ssp, chan_general, EBUS_IDX_ALARM,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2set, bits2clear);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * disable the reset function if we have enabled
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * it. We don't want any nasty surprises like system
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * rebooting unexpectedly. If we timeout on the busy
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * flag we just have to carry on.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'W', "bscv_cleanup",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_cleanup - disable wdog");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_get8_cached(ssp, EBUS_IDX_WDOG_CTRL) &
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_WDOG_ENABLE) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setclear8(ssp, chan_general, EBUS_IDX_WDOG_CTRL,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd 0, EBUS_WDOG_RST | EBUS_WDOG_ENABLE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * unmap registers
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_MAPPED_REGS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_unmap_regs(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * release any memory allocated for mutexes and condition
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * variables before deallocating the structures containing them
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->progress & BSCV_LOCKS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_destroy(&ssp->task_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_destroy(&ssp->task_evnt_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_destroy(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_destroy(&ssp->prog_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_destroy(&ssp->cmd_mutex);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->image != NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd kmem_free((void *)ssp->image, BSC_IMAGE_MAX_SIZE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_cyclic_remove(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_soft_state_free(bscv_statep, instance);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_setup_capability
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - probe the lom find what capabilities are present for
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * us to use.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - returns DDI_SUCCESS or DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_capability(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->prog_mode_only) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Turn off all capabilities */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap0 = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap1 = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap2 = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap0 = bscv_get8(ssp, chan_general, EBUS_IDX_CAP0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap1 = bscv_get8(ssp, chan_general, EBUS_IDX_CAP1);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap2 = bscv_get8(ssp, chan_general, EBUS_IDX_CAP2);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!bscv_faulty(ssp)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_setup_capability",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Capability flags cap0=0x%x cap1=0x%x, cap2=0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap0, ssp->cap1, ssp->cap2);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!Could not read capability flags");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->cap0 = 0; ssp->cap1 = 0; ssp->cap2 = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_probe_check
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - probe the lom to check for correct operation
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * has a side effect of setting up the cached registers and
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * updates ssp->prog_mode_only.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - returns DDI_SUCCESS or DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic int bscv_probe_check(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t probeval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check", "");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->prog_mode_only) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Make sure probe location is OK so that we are
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * in sync.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We want to make sure that this is not faulty so we
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * do a bscv_clear_fault to clear any existing
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * fault records down.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_clear_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd probeval = bscv_get8(ssp, chan_general, EBUS_IDX_PROBEAA);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (probeval != 0xAA) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "LOMlite out of sync");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * It may be that the LOMlite was out of
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * sync so lets try the read again.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd probeval = bscv_get8(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_PROBEAA);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Init readAA1 failed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (probeval != 0xAA) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * OK that is twice we are out so I
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * guess the LOMlite is in trouble
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Init readAA probe failed - got 0x%x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd probeval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Read in all page zero lom registers.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Read state change 1st so we dont miss anything and clear it.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note: we discard the values because we rely on bscv_get8 to
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * setup the cache of register values.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->prog_mode_only) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, EBUS_IDX_STATE_CHNG);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Read of state change register failed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->prog_mode_only) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 1; i < 0x80; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd switch (i) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_STATE_CHNG:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_CMD_RES:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd case EBUS_IDX_HNAME_CHAR:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Should not read these - they have side
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * effects.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd default:
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_get8(ssp, chan_general, i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Initial read or register %2x failed", i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Might as well give up now! */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Check the probe keys so we know the lom is OK
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!ssp->prog_mode_only) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((bscv_get8_cached(ssp, EBUS_IDX_PROBE55) != 0x55) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (bscv_get8_cached(ssp, EBUS_IDX_PROBEAA) != 0xAA)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "LOMlite Probe failed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < 0x8; i++) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_probe_check",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "%2x %2x %2x %2x %2x %2x %2x %2x %2x "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "%2x %2x %2x %2x %2x %2x %2x %2x %2x",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 1),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 2),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 3),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 4),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 5),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 6),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 7),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 8),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 9),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 10),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 11),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 12),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 13),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 14),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_get8_cached(ssp, i + 15));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->prog_mode_only = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return ((ssp->prog_mode_only == B_FALSE) ? DDI_SUCCESS : DDI_FAILURE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_idi_set
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - bscv inter driver interface set function
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - structure which defines type of service required and data
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * ouputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This is the Entry Point function for the platmod driver. It works out which
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * X Bus channel ought to deliver the service requested.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdvoid
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_idi_set(struct bscv_idi_info info)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd struct bscv_idi_callout *tbl;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t retval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_mgr.tbl == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_idi_set : cannot find "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_callout_table");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (bscv_idi_mgr.valid_inst == (uint32_t)~0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This error message can appear in the context of
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * another driver, say platmod or todblade. We want
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * to clearly indicate the culprit driver so put in
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the driver name.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_idi_set : no valid "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "driver instance of "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd MYNAME);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd tbl = bscv_idi_mgr.tbl;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (tbl->type != BSCV_IDI_NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (tbl->type == info.type) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We service the request with a valid instance number
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * for the driver.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd retval = ((tbl->fn) (info));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * If the request was serviced, clear any accumulated
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * error counters so future warnings will be reported if
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * seen.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (retval == B_TRUE)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_idi_clear_err();
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd tbl++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_idi_set : cannot match info.type %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd info.type);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_nodename_set
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - notify the event thread that a nodename change has occurred.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - data from client driver
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * side-effects - the event thread will schedule an update to the lom firmware.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_nodename_set(struct bscv_idi_info info)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!blade_nodename_set: cannot get ssp");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Get a lock on the SSP, notify our change, then exit */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_enter(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->nodename_change = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cv_signal(&ssp->task_cv);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mutex_exit(&ssp->task_mu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_sig_set
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - write a signature
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - data from client driver
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_sig_set(struct bscv_idi_info info)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_sig_t sig;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!blade_nodename_set: cannot get ssp");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Service the request */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bcopy(info.data, &sig, sizeof (sig));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_enter(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_write_sig(ssp, sig);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_exit(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_wdog_do_pat(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t pat;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The value of the dog pat is a sequence number which wraps around,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bounded by BSCV_WDOG_PAT_SEQ_MASK.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pat = ssp->pat_seq++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pat &= EBUS_WDOG_NB_PAT_SEQ_MASK;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Set top nibble to indicate a pat */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pat |= EBUS_WDOG_NB_PAT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Now pat the dog. This exercises a special protocol in the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bus nexus that offers : non-blocking IO, and timely delivery,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * callable from high-level interrupt context. The requirement
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * on us is that the channel is not shared for any other use.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This means for chan_wdogpat, nothing may use channel[chan].regs
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * or channel.[chan].handle.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_put8(ssp->channel[chan_wdogpat].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->channel[chan_wdogpat].regs, pat);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'W', "bscv_wdog_pat", "patted the dog with seq %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd pat);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_wdog_pat
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - pat the watchdog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - data from client driver
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_wdog_pat(struct bscv_idi_info info)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This function remembers if it has ever been called with the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * configure option set.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_wdog_pat: cannot get ssp");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->nchannels == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Didn't manage to map handles so ddi_{get,put}* broken */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_wdog_pat: handle not mapped");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_wdog_do_pat(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_wdog_cfg
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - configure the watchdog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - data from client driver
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_wdog_cfg(struct bscv_idi_info info)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_wdog_cfg: cannot get ssp");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->nchannels == 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Didn't manage to map handles so ddi_{get,put}* broken */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_idi_err())
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "!bscv_wdog_cfg: handle not mapped");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (sizeof (bscv_wdog_t) != info.size) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'W', "bscv_wdog_set", "data passed in is size"
1c42de6d020629af774dd9e9fc81be3f3ed9398egd " %d instead of %d", info.size,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (bscv_wdog_t));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_FALSE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'W', "bscv_wdog_cfg", "enable_wdog %s, "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "wdog_timeout_s %d, reset_system_on_timeout %s",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((bscv_wdog_t *)info.data)->enable_wdog ? "enabled" : "disabled",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((bscv_wdog_t *)info.data)->wdog_timeout_s,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((bscv_wdog_t *)info.data)->reset_system_on_timeout ? "yes" : "no");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_write_wdog_cfg(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((bscv_wdog_t *)info.data)->wdog_timeout_s,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((bscv_wdog_t *)info.data)->enable_wdog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((bscv_wdog_t *)info.data)->reset_system_on_timeout);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (B_TRUE);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_write_wdog_cfg(bscv_soft_state_t *ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint_t wdog_timeout_s,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t enable_wdog,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t reset_system_on_timeout)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t cfg = EBUS_WDOG_NB_CFG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Configure the timeout value (1 to 127 seconds).
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Note that a policy is implemented at the bsc/ssp which bounds
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the value further. The bounding here is to fit the timeout value
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * into the 7 bits the bsc uses.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (wdog_timeout_s < 1)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->watchdog_timeout = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd else if (wdog_timeout_s > 127)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->watchdog_timeout = 127;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd else
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->watchdog_timeout = wdog_timeout_s;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Configure the watchdog on or off.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (enable_wdog)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cfg |= EBUS_WDOG_NB_CFG_ENB;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd else
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cfg &= ~EBUS_WDOG_NB_CFG_ENB;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Configure whether the microcontroller should reset the system when
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * the watchdog expires.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->watchdog_reset_on_timeout = reset_system_on_timeout;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ddi_put8(ssp->channel[chan_wdogpat].handle,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->channel[chan_wdogpat].regs, cfg);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* have the event daemon set the timeout value and whether to reset */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->watchdog_change = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'W', "bscv_wdog_cfg",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "configured the dog with cfg 0x%x", cfg);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_setup_watchdog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - setup the bsc watchdog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs -
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_watchdog(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t set = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t clear = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd extern int watchdog_activated;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Set the timeout */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_WDOG_TIME, ssp->watchdog_timeout);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Set whether to reset the system on timeout */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->watchdog_reset_on_timeout) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd set |= EBUS_WDOG_RST;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd clear |= EBUS_WDOG_RST;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (watchdog_activated) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd set |= EBUS_WDOG_ENABLE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd clear |= EBUS_WDOG_ENABLE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Set other host defaults */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd clear |= (EBUS_WDOG_BREAK_DISABLE | EBUS_WDOG_AL3_FANPSU
1c42de6d020629af774dd9e9fc81be3f3ed9398egd | EBUS_WDOG_AL3_WDOG);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setclear8_volatile(ssp, chan_general, EBUS_IDX_WDOG_CTRL,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd set, clear);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* start the cyclic based watchdog patter */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_cyclic_add(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress |= BSCV_WDOG_CFG;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_setup_hostname
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - setup the lom hostname if different from the nodename
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void bscv_setup_hostname(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char host_nodename[128];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char lom_nodename[128];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size_t hostlen;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd size_t nodelen;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Check machine label is the same as the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * system nodename.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) strncpy(host_nodename, utsname.nodename,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd sizeof (host_nodename));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* read in lom hostname */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_read_hostname(ssp, lom_nodename);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Enforce null termination */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd host_nodename[sizeof (host_nodename) - 1] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_nodename[sizeof (lom_nodename) - 1] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd hostlen = (size_t)bscv_get8(ssp, chan_general, EBUS_IDX_HNAME_LENGTH);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nodelen = (size_t)strlen(host_nodename);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((nodelen > 0) &&
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ((hostlen != nodelen) || (strcmp((const char *)&lom_nodename,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (const char *)&host_nodename)) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (hostlen == 0))) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_setup_hostname",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "nodename(%s,%d) != bsc label(%s,%d)",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd host_nodename, nodelen, lom_nodename, hostlen);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Write new label into LOM EEPROM */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_write_hostname(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd host_nodename,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint8_t)strlen(host_nodename));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress |= BSCV_HOSTNAME_DONE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_read_hostname
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - read the current hostname from the lom
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state pointer and buffer to store the hostname in.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_read_hostname(bscv_soft_state_t *ssp, char *lom_nodename)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int num_failures;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t needretry;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int length;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We have a special failure case here because a retry of a read
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * causes data to be lost. Thus we handle the retries ourselves
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and are also responsible for detemining if the lom is faulty
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (num_failures = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures < BSC_FAILURE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_clear_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd length = bscv_get8(ssp, chan_general, EBUS_IDX_HNAME_LENGTH);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < length; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_nodename[i] = bscv_get8_once(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_general, EBUS_IDX_HNAME_CHAR);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Retry on any error */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_retcode(ssp) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* null terminate for strcmp later */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_nodename[length] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Force the nodename to be empty */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd lom_nodename[0] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Failure - we ran out of retries */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_read_hostname: retried %d times, giving up",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_fault = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (num_failures > 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'R', "bscv_read_hostname",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "retried %d times, succeeded", num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_write_hostname
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - write a new hostname to the lom
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state pointer, pointer to new name, name length
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_write_hostname(bscv_soft_state_t *ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *host_nodename, uint8_t length)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int num_failures;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd boolean_t needretry;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We have a special failure case here because a retry of a read
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * causes data to be lost. Thus we handle the retries ourselves
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and are also responsible for detemining if the lom is faulty
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (num_failures = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures < BSC_FAILURE_RETRY_LIMIT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_clear_fault(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_general, EBUS_IDX_HNAME_LENGTH, length);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_faulty(ssp)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < length; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8_once(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_HNAME_CHAR, host_nodename[i]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Retry on any error */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_retcode(ssp) != 0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd needretry = 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (!needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (needretry) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Failure - we ran out of retries */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_write_hostname: retried %d times, giving up",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->had_fault = B_TRUE;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (num_failures > 0) {
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'R', "bscv_write_hostname",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "retried %d times, succeeded", num_failures);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_setup_static_info
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - read in static information from the lom at attach time.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_setup_static_info(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t addr_space_ptr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint16_t mask;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t fanspeed;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int oldtemps[MAX_TEMPS];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int8_t temp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Finally read in some static info like device names,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * shutdown enabled, etc before the queue starts.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * To get the volts static info we need address space 2
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(&ssp->volts, sizeof (lom_volts_t));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->volts.num = EBUS_CONFIG2_NSUPPLY_DEC(
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG2));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->volts.num > MAX_VOLTS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom: firmware reported too many voltage lines. ");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT, "Reported %d, maximum is %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->volts.num, MAX_VOLTS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->volts.num = MAX_VOLTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_setup_static_info",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "num volts %d", ssp->volts.num);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_read_env_name(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CMD_SPACE2,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX2_SUPPLY_NAME_START,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX2_SUPPLY_NAME_END,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->volts.name,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->volts.num);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mask = bscv_get8(ssp, chan_general, BSCVA(EBUS_CMD_SPACE2,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX2_SUPPLY_FATAL_MASK1)) << 8;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd mask |= bscv_get8(ssp, chan_general, BSCVA(EBUS_CMD_SPACE2,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX2_SUPPLY_FATAL_MASK2));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->volts.num; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->volts.shutdown_enabled[i] =
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (((mask >> i) & 1) == 0) ? 0 : 1;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Get the temperature static info and populate initial temperatures.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Do not destroy old temperature values if the new value is not
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * known i.e. if the device is inaccessible.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bcopy(ssp->temps.temp, oldtemps, sizeof (oldtemps));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(&ssp->temps, sizeof (lom_temp_t));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num = EBUS_CONFIG2_NTEMP_DEC(
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG2));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->temps.num > MAX_TEMPS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom: firmware reported too many temperatures being "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "monitored.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT, "Reported %d, maximum is %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num, MAX_TEMPS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num = MAX_TEMPS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num_ov = EBUS_CONFIG3_NOTEMP_DEC(
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG3));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->temps.num_ov > MAX_TEMPS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom: firmware reported too many over temperatures being "
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "monitored.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT, "Reported %d, maximum is %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num_ov, MAX_TEMPS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num_ov = MAX_TEMPS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_setup_static_info",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "num temps %d, over temps %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num, ssp->temps.num_ov);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr_space_ptr = bscv_read_env_name(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CMD_SPACE4,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX4_TEMP_NAME_START,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX4_TEMP_NAME_END,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.name,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->temps.num; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.warning[i] = (int8_t)bscv_get8(ssp, chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE4, EBUS_IDX4_TEMP_WARN1 + i));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * If shutdown is not enabled then set it as zero so
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * it is not displayed by the utility.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((bscv_get8(ssp, chan_general, BSCVA(EBUS_CMD_SPACE4,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX4_TEMP_FATAL_MASK)) >> i) & 0x01) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.shutdown[i] = (int8_t)bscv_get8(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE4, EBUS_IDX4_TEMP_SDOWN1 + i));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.shutdown[i] = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->temps.num; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd temp = bscv_get8(ssp, chan_general, EBUS_IDX_TEMP1 + i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((temp <= LOM_TEMP_MAX_VALUE) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (temp == LOM_TEMP_STATE_NOT_PRESENT)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.temp[i] = temp;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* New value is not known - use old value */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.temp[i] = oldtemps[i];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Check for and skip a single 0xff character between the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * temperature and over temperature names
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_get8(ssp, chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE4, addr_space_ptr)) == 0xff) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr_space_ptr++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_read_env_name(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CMD_SPACE4,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr_space_ptr,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX4_TEMP_NAME_END,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.name_ov,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->temps.num_ov);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * To get the CB static info we need address space 3
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(&ssp->sflags, sizeof (lom_sflags_t));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->sflags.num = EBUS_CONFIG3_NBREAKERS_DEC(bscv_get8(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd chan_general, EBUS_IDX_CONFIG3));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->sflags.num > MAX_STATS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom: firmware reported too many status flags.");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Reported %d, maximum is %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->sflags.num, MAX_STATS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->sflags.num = MAX_STATS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_setup_static_info",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "num sflags %d", ssp->sflags.num);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_read_env_name(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CMD_SPACE3,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX3_BREAKER_NAME_START,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX3_BREAKER_NAME_END,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->sflags.name,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->sflags.num);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * To get the fan static info we need address space 5
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->num_fans = EBUS_CONFIG_NFAN_DEC(
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->num_fans > MAX_FANS) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "lom: firmware reported too many fans. ");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "Reported %d, maximum is %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->num_fans, MAX_FANS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->num_fans = MAX_FANS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < ssp->num_fans; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd fanspeed = bscv_get8(ssp, chan_general,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota EBUS_IDX_FAN1_SPEED + i);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if ((fanspeed <= LOM_FAN_MAX_SPEED) ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (fanspeed == LOM_FAN_NOT_PRESENT)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Do not destroy previous values unless the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * value is definitive.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->fanspeed[i] = fanspeed;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_setup_static_info",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "num fans %d", ssp->num_fans);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_read_env_name(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CMD_SPACE5,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX5_FAN_NAME_START,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX5_FAN_NAME_END,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->fan_names,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->num_fans);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Get led static information from address space 10 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) bscv_read_env_name(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_CMD_SPACE_LEDS,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX10_LED_NAME_START,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_IDX10_LED_NAME_END,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->led_names,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd MAX_LED_ID);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_read_env_name
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - read in static environment names
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * warning changes address space and the caller relies
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * on this behaviour.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr, chosen address space,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * start of name data, end of name data,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * name storage, number of names.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - next address for reading name data.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint8_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_read_env_name(bscv_soft_state_t *ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t addr_space,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t addr_start,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t addr_end,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char namebuf[][MAX_LOM2_NAME_STR],
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int numnames)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int i;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int nameidx;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd int namemax;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd unsigned int addr_space_ptr;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t this_char;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'A', "bscv_read_env_name",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_read_env_name, space %d, start 0x%x, end 0x%x, numnames %d",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr_space, addr_start, addr_end, numnames);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr_space_ptr = addr_start;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd for (i = 0; i < numnames; i++) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd nameidx = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd namemax = sizeof (namebuf[i]);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bzero(namebuf[i], namemax);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd while (addr_space_ptr <= addr_end) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Read the current character.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd this_char = bscv_get8(ssp, chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(addr_space, addr_space_ptr));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (this_char == 0xff) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Ran out of names - this must
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * be the end of the name.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This is really an error because
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * we have just seen either a non-NUL
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * terminated string or the number of
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * strings did not match what was
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * reported.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We increment the buffer pointer now so that
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * it is ready for the next read
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr_space_ptr++;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (this_char == '\0') {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Found end of string - done */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd break;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (nameidx < (namemax - 1)) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * Buffer not full - record character
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * NOTE we always leave room for the NUL
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * terminator.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd namebuf[i][nameidx++] = this_char;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Ensure null termination */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd namebuf[i][nameidx] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Clamp addr_space_ptr to 0xff because we return uint8_t */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (addr_space_ptr > 0xff) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd addr_space_ptr = 0xff;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (addr_space_ptr);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_setup_events
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - initialise the event reporting code
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS or DDI_FAILURE
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_setup_events(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t bits2set;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd uint8_t bits2clear;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * deal with event reporting - cover all cases
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2set = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2clear = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->serial_reporting == LOM_SER_EVENTS_ON) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2clear |= EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->serial_reporting == LOM_SER_EVENTS_OFF) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2set |= EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else if (ssp->serial_reporting == LOM_SER_EVENTS_DEF) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bits2set |= EBUS_ALARM_NOEVENTS;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_setclear8_volatile(ssp, chan_general, EBUS_IDX_ALARM,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota bits2set, bits2clear);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef __sparc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_write_sig
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - write out a signature, taking care to deal with any strange
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * values for CPU ID
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr, signature
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_write_sig(bscv_soft_state_t *ssp, bscv_sig_t s)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* Upload the signature */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put32(ssp, chan_cpusig,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_SIG_MSB),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd s.sig_info.signature);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We always write the CPU ID last because this tells the firmware
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * that the signature is fully uploaded and therefore to consume the
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * data. This is required since the signature is > 1 byte in size
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * and we transmit data in single bytes.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (s.cpu == ~0) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /* ~0 means the signature applies to any CPU. */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_cpusig,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_ID),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd EBUS_ANY_CPU_ID);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd } else {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (s.cpu > 255) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * The CPU ID supplied is unexpectedly large. Lets
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * just use the bottom bits, in case other high order
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * bits are being used for special meaning.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_WARN, "CPU Signature ID 0x%x > 255", s.cpu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd s.cpu %= 256;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd cmn_err(CE_CONT, "using ID 0x%x instead ", s.cpu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_cpusig,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_ID),
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (uint8_t)s.cpu);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->last_sig = s;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ssp->progress |= BSCV_SIG_SENT;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __sparc */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#if defined(__i386) || defined(__amd64)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_inform_bsc
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - inform bsc of driver state for logging purposes
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - driver soft state, state
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_inform_bsc(bscv_soft_state_t *ssp, uint32_t state)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(bscv_held(ssp));
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_inform_bsc",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "bscv_inform_bsc: state=%d", state);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put32(ssp, chan_general,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_SIG_MSB), state);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_put8(ssp, chan_cpusig,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_ID), EBUS_ANY_CPU_ID);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_watchdog_pat_request
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - request a heartbeat pat
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - timeout value in seconds
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_watchdog_pat_request(void *arg)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp = (bscv_soft_state_t *)arg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_wdog_do_pat(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_watchdog_cfg_request
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - request configuration of the bsc hardware watchdog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - new state (0=disabled, 1=enabled)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - one if successful, zero if unsuccesful
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_watchdog_cfg_request(bscv_soft_state_t *ssp, uint8_t new_state)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd ASSERT(new_state == WDOG_ON || new_state == WDOG_OFF);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd watchdog_activated = new_state;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_watchdog_cfg_request",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "watchdog_activated=%d", watchdog_activated);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_write_wdog_cfg(ssp,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_timeout_seconds,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd new_state,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd wdog_reset_on_timeout);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_set_watchdog_timer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - setup the heartbeat timeout value
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - timeout value in seconds
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - zero if the value was not changed
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * otherwise the current value
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic uint_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_set_watchdog_timer(bscv_soft_state_t *ssp, uint_t timeoutval)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_set_watchdog_timer:",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "timeout=%d", timeoutval);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We get started during bscv_attach only
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * if bscv_watchdog_enable is set.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_watchdog_available && (!watchdog_activated ||
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (watchdog_activated &&
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota (timeoutval != bscv_watchdog_timeout_seconds)))) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_timeout_seconds = timeoutval;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_cfg_request(ssp, WDOG_ON);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (bscv_watchdog_timeout_seconds);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (0);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_clear_watchdog_timer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - add the watchdog patter cyclic
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - driver soft state
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - value of watchdog timeout in seconds
1c42de6d020629af774dd9e9fc81be3f3ed9398egd *
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * This function is a copy of the SPARC implementation
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * in the todblade clock driver.
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_clear_watchdog_timer(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_clear_watchdog_timer", "");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (bscv_watchdog_available && watchdog_activated) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_enable = 0;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_watchdog_cfg_request(ssp, WDOG_OFF);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_panic_callback
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - called when we panic so we can disabled the watchdog
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - driver soft state pointer
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - DDI_SUCCESS
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*ARGSUSED1*/
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic boolean_t
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_panic_callback(void *arg, int code)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_soft_state_t *ssp = (bscv_soft_state_t *)arg;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_panic_callback",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "disabling watchdog");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_clear_watchdog_timer(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd /*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * We dont get interrupts during the panic callback. But bscbus
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * takes care of all this
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd bscv_full_stop(ssp);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return (DDI_SUCCESS);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_watchdog_cyclic_add
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - add the watchdog patter cyclic
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - driver soft state
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_watchdog_cyclic_add(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota if (ssp->periodic_id != NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ssp->periodic_id = ddi_periodic_add(bscv_watchdog_pat_request, ssp,
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota WATCHDOG_PAT_INTERVAL, DDI_IPL_10);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_watchdog_cyclic_add:",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "cyclic added");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * function - bscv_watchdog_cyclic_remove
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * description - remove the watchdog patter cyclic
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * inputs - soft state ptr
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * outputs - none
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_watchdog_cyclic_remove(bscv_soft_state_t *ssp)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota if (ssp->periodic_id == NULL) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd return;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ddi_periodic_delete(ssp->periodic_id);
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota ssp->periodic_id = NULL;
1af83355f7af9ab90e0c801c0224182053a04533andrew.rutz@sun.com BSCV_TRACE(ssp, 'X', "bscv_watchdog_cyclic_remove:",
1c42de6d020629af774dd9e9fc81be3f3ed9398egd "cyclic removed");
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* __i386 || __amd64 */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd/*
1c42de6d020629af774dd9e9fc81be3f3ed9398egd * General utility routines ...
1c42de6d020629af774dd9e9fc81be3f3ed9398egd */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#ifdef DEBUG
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_trace(bscv_soft_state_t *ssp, char code, const char *caller,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd const char *fmt, ...)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char buf[256];
1c42de6d020629af774dd9e9fc81be3f3ed9398egd char *p;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd va_list va;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd if (ssp->debug & (1 << (code-'@'))) {
1c42de6d020629af774dd9e9fc81be3f3ed9398egd p = buf;
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) snprintf(p, sizeof (buf) - (p - buf),
dd4eeefdb8e4583c47e28a7f315db6087931ef06eota "%s/%s: ", MYNAME, caller);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd p += strlen(p);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd va_start(va, fmt);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) vsnprintf(p, sizeof (buf) - (p - buf), fmt, va);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd va_end(va);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd buf[sizeof (buf) - 1] = '\0';
1c42de6d020629af774dd9e9fc81be3f3ed9398egd (void) strlog((short)ssp->majornum, (short)ssp->minornum, code,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd SL_TRACE, buf);
1c42de6d020629af774dd9e9fc81be3f3ed9398egd }
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#else /* DEBUG */
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd_NOTE(ARGSUSED(0))
1c42de6d020629af774dd9e9fc81be3f3ed9398egdstatic void
1c42de6d020629af774dd9e9fc81be3f3ed9398egdbscv_trace(bscv_soft_state_t *ssp, char code, const char *caller,
1c42de6d020629af774dd9e9fc81be3f3ed9398egd const char *fmt, ...)
1c42de6d020629af774dd9e9fc81be3f3ed9398egd{
1c42de6d020629af774dd9e9fc81be3f3ed9398egd}
1c42de6d020629af774dd9e9fc81be3f3ed9398egd
1c42de6d020629af774dd9e9fc81be3f3ed9398egd#endif /* DEBUG */