29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER START
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * The contents of this file are subject to the terms of the
29949e866e40b95795203f3ee46f44a197c946e4stevel * Common Development and Distribution License (the "License").
29949e866e40b95795203f3ee46f44a197c946e4stevel * You may not use this file except in compliance with the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
29949e866e40b95795203f3ee46f44a197c946e4stevel * or http://www.opensolaris.org/os/licensing.
29949e866e40b95795203f3ee46f44a197c946e4stevel * See the License for the specific language governing permissions
29949e866e40b95795203f3ee46f44a197c946e4stevel * and limitations under the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * When distributing Covered Code, include this CDDL HEADER in each
29949e866e40b95795203f3ee46f44a197c946e4stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
29949e866e40b95795203f3ee46f44a197c946e4stevel * If applicable, add the following below this CDDL HEADER, with the
29949e866e40b95795203f3ee46f44a197c946e4stevel * fields enclosed by brackets "[]" replaced with your own identifying
29949e866e40b95795203f3ee46f44a197c946e4stevel * information: Portions Copyright [yyyy] [name of copyright owner]
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER END
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Use is subject to license terms.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#pragma ident "%Z%%M% %I% %E% SMI"
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/types.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/conf.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/ddi.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sunddi.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/ddi_impldefs.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/obpdefs.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/promif.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/cmn_err.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/errno.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/kmem.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/kstat.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/debug.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/fhc.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/jtag.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sysctrl.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic fhc_bd_resizable_t boards; /* booted and hotplugged boards */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic fhc_bd_resizable_t clocks; /* clocks under central. */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int fhc_bdmax;
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * !! IMPORTANT !! fhc_bdlist_rwlock is implemented as a single
29949e866e40b95795203f3ee46f44a197c946e4stevel * RW_WRITER lock with *no* RW_READERs -- and it should stay that
29949e866e40b95795203f3ee46f44a197c946e4stevel * way. The fhc_bdlist_rwlock should never be used with RW_READER.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * The lock was originally a mutex, but was changed to a
29949e866e40b95795203f3ee46f44a197c946e4stevel * single-writer, zero-reader rwlock to force requesting threads
29949e866e40b95795203f3ee46f44a197c946e4stevel * to block (sleep, not spin) when the RW_WRITER lock is already
29949e866e40b95795203f3ee46f44a197c946e4stevel * held by a thread currently running.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic krwlock_t fhc_bdlist_rwlock;
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic sysc_evt_handle_t fhc_bd_evt;
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic sysc_evt_handle_t *fbe = &fhc_bd_evt;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#define fhc_bd_sc_evt(s, e) (*fbe->update)(fbe->soft, s, e)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define FHC_INCREMENT 4
29949e866e40b95795203f3ee46f44a197c946e4stevel#define FHC_B_SEARCH(in_array, board) \
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_b_search(in_array.boards, board, 0, in_array.last);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int fhc_bd_disabled(int);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void fhc_check_array(int);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void fhc_shell_sort(fhc_bd_t **, int, int);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int fhc_b_search(fhc_bd_t **, int, int, int);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void fhc_check_size(fhc_bd_resizable_t *);
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void fhc_resize(fhc_bd_t ***, int, int);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * fhc_bdmax gets set in fhc_bdlist_prime() and does not
29949e866e40b95795203f3ee46f44a197c946e4stevel * change thereafter.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_max_boards()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel return (fhc_bdmax + 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_disabled(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(index != -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[index]->flags & BDF_DISABLED);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_check_array(int btype)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel if (btype == FHC_BOARDS) {
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!boards.sorted) {
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_shell_sort(boards.boards, 0, boards.last);
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.sorted = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!clocks.sorted) {
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_shell_sort(clocks.boards, 0, clocks.last);
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.sorted = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_shell_sort(fhc_bd_t *a[], int lb, int ub)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int n, h, i, j;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *t;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* sort array a[lb..ub] */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* compute largest increment */
29949e866e40b95795203f3ee46f44a197c946e4stevel n = ub - lb + 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel h = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (n < 14)
29949e866e40b95795203f3ee46f44a197c946e4stevel h = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel else {
29949e866e40b95795203f3ee46f44a197c946e4stevel while (h < n)
29949e866e40b95795203f3ee46f44a197c946e4stevel h = 3 * h + 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel h /= 3;
29949e866e40b95795203f3ee46f44a197c946e4stevel h /= 3;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel while (h > 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* sort-by-insertion in increments of h */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = lb + h; i <= ub; i++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel t = a[i];
29949e866e40b95795203f3ee46f44a197c946e4stevel for (j = i - h;
29949e866e40b95795203f3ee46f44a197c946e4stevel j >= lb && a[j]->sc.board > t->sc.board;
29949e866e40b95795203f3ee46f44a197c946e4stevel j -= h) {
29949e866e40b95795203f3ee46f44a197c946e4stevel a[j+h] = a[j];
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel a[j+h] = t;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* compute next increment */
29949e866e40b95795203f3ee46f44a197c946e4stevel h /= 3;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_b_search(fhc_bd_t *in_array[], int board, int first, int last)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int mid;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Array of length 0 case. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (in_array == NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Array of length > 0 case. */
29949e866e40b95795203f3ee46f44a197c946e4stevel while (first < last) {
29949e866e40b95795203f3ee46f44a197c946e4stevel mid = (first + last) / 2;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (in_array[mid]->sc.board < board)
29949e866e40b95795203f3ee46f44a197c946e4stevel first = mid + 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel last = mid;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (in_array[first]->sc.board == board) {
29949e866e40b95795203f3ee46f44a197c946e4stevel return (first);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_check_size(fhc_bd_resizable_t *resizable)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int oldsize;
29949e866e40b95795203f3ee46f44a197c946e4stevel int newsize;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (resizable->size == resizable->last + 1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel oldsize = sizeof (fhc_bd_t *) * resizable->size;
29949e866e40b95795203f3ee46f44a197c946e4stevel resizable->size += FHC_INCREMENT;
29949e866e40b95795203f3ee46f44a197c946e4stevel newsize = sizeof (fhc_bd_t *) * resizable->size;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_resize(&(resizable->boards), oldsize, newsize);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_locked()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel if (panicstr)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (rw_owner(&fhc_bdlist_rwlock) == curthread);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_busy(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(index != -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[index]->sc.in_transition);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_is_jtag_master(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(index != -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (boards.boards[index]->softsp == NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel return ((boards.boards[index]->softsp)->jt_master.is_master);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_is_plus(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(index != -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (boards.boards[index]->sc.plus_board)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[index]->sc.plus_board);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel return (FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_init()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(!fhc_bdmax);
29949e866e40b95795203f3ee46f44a197c946e4stevel rw_init(&fhc_bdlist_rwlock, NULL, RW_DEFAULT, NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.size = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.last = -1;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.sorted = TRUE; /* Array of 0 elements is sorted. */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.boards = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.size = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.last = -1;
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.sorted = TRUE; /* Array of 0 elements is sorted. */
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_fini()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel rw_destroy(&fhc_bdlist_rwlock);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_t *
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_lock(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(!fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* RW_WRITER *ONLY*. Never use RW_READER! */
29949e866e40b95795203f3ee46f44a197c946e4stevel rw_enter(&fhc_bdlist_rwlock, RW_WRITER);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (board == -1)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel else {
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(index != -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[index]);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_unlock()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel rw_exit(&fhc_bdlist_rwlock);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_resize(fhc_bd_t ***in_array, int oldsize, int newsize)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t **temp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* This function only grows arrays. */
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(newsize > oldsize);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Allocate new array. */
29949e866e40b95795203f3ee46f44a197c946e4stevel temp = kmem_alloc(newsize, KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Bcopy old array and free it. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (*in_array != NULL) {
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(oldsize > 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel bcopy(*in_array, temp, oldsize);
29949e866e40b95795203f3ee46f44a197c946e4stevel kmem_free(*in_array, oldsize);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel *in_array = temp;
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_init(struct fhc_soft_state *softsp, int board, enum board_type type)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* See if board already exists. */
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(clocks.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (softsp->is_central) {
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(clocks, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If index == -1 board does not exist. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (index != -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (softsp->is_central) {
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = clocks.boards[index];
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = boards.boards[index];
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (softsp->is_central) {
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_check_size(&clocks);
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.boards[clocks.last + 1] =
29949e866e40b95795203f3ee46f44a197c946e4stevel kmem_zalloc(sizeof (fhc_bd_t), KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = clocks.boards[clocks.last + 1];
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.last++;
29949e866e40b95795203f3ee46f44a197c946e4stevel clocks.sorted = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_check_size(&boards);
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards[boards.last + 1] =
29949e866e40b95795203f3ee46f44a197c946e4stevel kmem_zalloc(sizeof (fhc_bd_t), KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = boards.boards[boards.last + 1];
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.last++;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.sorted = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel softsp->list = bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->flags |= BDF_VALID;
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->softsp = softsp;
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->sc.type = type;
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->sc.board = board;
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->sc.plus_board = ISPLUSBRD(*softsp->bsr);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Keep arrays sorted. */
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_check_array(FHC_BOARDS);
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_check_array(FHC_CLOCKS);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_t *
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (fhc_bdmax) {
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(index != -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[index]);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_t *
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_clock(void)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(clocks.size != 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (clocks.boards[0]);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_t *
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_first()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel if (boards.boards != NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[0]);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel return (NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_t *
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_next(fhc_bd_t *bdp)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, bdp->sc.board);
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(index != -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (index < boards.last)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[index + 1]);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel return (NULL);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_valid(int bd)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(bd >= 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Untill fhc_bdlist_prime runs anything is valid. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!fhc_bdmax)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, bd);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (index == -1)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel return (TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelenum board_type
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_type(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(boards.sorted);
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (index == -1)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (boards.boards[index]->sc.type);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelchar *
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_typestr(enum board_type type)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel char *type_str;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (type) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case MEM_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = MEM_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case CPU_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = CPU_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_2SBUS_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = IO_2SBUS_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_SBUS_FFB_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = IO_SBUS_FFB_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_2SBUS_SOCPLUS_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = IO_2SBUS_SOCPLUS_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_SBUS_FFB_SOCPLUS_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = IO_SBUS_FFB_SOCPLUS_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case IO_PCI_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = IO_PCI_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case DISK_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = DISK_BD_NAME;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel case UNKNOWN_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel type_str = "unknown";
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (type_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_env_set(int board, void *env)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->dev_softsp = env;
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_dlist_init()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel int len;
29949e866e40b95795203f3ee46f44a197c946e4stevel int board;
29949e866e40b95795203f3ee46f44a197c946e4stevel pnode_t node;
29949e866e40b95795203f3ee46f44a197c946e4stevel char *dlist;
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Find the disabled board list property if present.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * The disabled board list is in the options node under root;
29949e866e40b95795203f3ee46f44a197c946e4stevel * it is a null terminated list of boards in a string.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Each char represents a board. The driver must
29949e866e40b95795203f3ee46f44a197c946e4stevel * reject illegal chars in case a user places them in the
29949e866e40b95795203f3ee46f44a197c946e4stevel * property.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (((node = prom_finddevice("/options")) == OBP_BADNODE) ||
29949e866e40b95795203f3ee46f44a197c946e4stevel ((len = prom_getproplen(node, "disabled-board-list")) == -1))
29949e866e40b95795203f3ee46f44a197c946e4stevel return;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel dlist = kmem_alloc(len, KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) prom_getprop(node, "disabled-board-list", dlist);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * now loop thru the string, and create disabled board list
29949e866e40b95795203f3ee46f44a197c946e4stevel * entries for all legal boards in the list.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0; (i < len) && (dlist[i] != 0); i++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel char ch = dlist[i];
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (ch >= '0' && ch <= '9')
29949e866e40b95795203f3ee46f44a197c946e4stevel board = ch - '0';
29949e866e40b95795203f3ee46f44a197c946e4stevel else if (ch >= 'A' && ch <= 'F')
29949e866e40b95795203f3ee46f44a197c946e4stevel board = ch - 'A' + 10;
29949e866e40b95795203f3ee46f44a197c946e4stevel else if (ch >= 'a' && ch <= 'f')
29949e866e40b95795203f3ee46f44a197c946e4stevel board = ch - 'a' + 10;
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel /* junk entry */
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel index = FHC_B_SEARCH(boards, board);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (index != -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards[index]->flags |= BDF_DISABLED;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel kmem_free(dlist, len);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic struct bd_info fhc_bd_info;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_ks_update(kstat_t *ksp, int rw)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel struct bd_info *uip;
29949e866e40b95795203f3ee46f44a197c946e4stevel enum board_state state;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (rw == KSTAT_WRITE)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EACCES);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = (fhc_bd_t *)ksp->ks_private;
29949e866e40b95795203f3ee46f44a197c946e4stevel uip = &fhc_bd_info;
29949e866e40b95795203f3ee46f44a197c946e4stevel sc = &bdp->sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_valid(sc->board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel uip->board = sc->board;
29949e866e40b95795203f3ee46f44a197c946e4stevel uip->type = sc->type;
29949e866e40b95795203f3ee46f44a197c946e4stevel uip->fhc_compid = sc->fhc_compid;
29949e866e40b95795203f3ee46f44a197c946e4stevel uip->ac_compid = sc->ac_compid;
29949e866e40b95795203f3ee46f44a197c946e4stevel bcopy((caddr_t)sc->prom_rev, uip->prom_rev, sizeof (uip->prom_rev));
29949e866e40b95795203f3ee46f44a197c946e4stevel bcopy((caddr_t)&sc->bd, &uip->bd, sizeof (union bd_un));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sc->rstate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_DISCONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sc->condition) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_OK:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNKNOWN:
29949e866e40b95795203f3ee46f44a197c946e4stevel state = DISABLED_STATE;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILING:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNUSABLE:
29949e866e40b95795203f3ee46f44a197c946e4stevel state = FAILED_STATE;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel state = UNKNOWN_STATE;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel state = UNKNOWN_STATE;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel uip->state = state;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_ks_alloc(fhc_bd_t *bdp)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(!bdp->ksp);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->ksp = kstat_create("unix", bdp->sc.board,
29949e866e40b95795203f3ee46f44a197c946e4stevel BDLIST_KSTAT_NAME, "misc", KSTAT_TYPE_RAW,
29949e866e40b95795203f3ee46f44a197c946e4stevel sizeof (struct bd_info), KSTAT_FLAG_VIRTUAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->ksp != NULL) {
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->ksp->ks_data = &fhc_bd_info;
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->ksp->ks_update = fhc_bd_ks_update;
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->ksp->ks_private = (void *)bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_install(bdp->ksp);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_dk_init()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel dev_info_t *dnode;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Search the children of root to see if there are any
29949e866e40b95795203f3ee46f44a197c946e4stevel * disk boards in the tree.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (dnode = ddi_get_child(ddi_root_node());
29949e866e40b95795203f3ee46f44a197c946e4stevel dnode != NULL; dnode = ddi_get_next_sibling(dnode)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strcmp(ddi_node_name(dnode), "disk-board") == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel int id;
29949e866e40b95795203f3ee46f44a197c946e4stevel int board;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Get the board number property.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((board = (int)ddi_getprop(DDI_DEV_T_ANY, dnode,
29949e866e40b95795203f3ee46f44a197c946e4stevel DDI_PROP_DONTPASS, OBP_BOARDNUM, -1)) == -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN,
29949e866e40b95795203f3ee46f44a197c946e4stevel "Could not find board number");
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel sc = &bdp->sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((id = (int)ddi_getprop(DDI_DEV_T_ANY, dnode,
29949e866e40b95795203f3ee46f44a197c946e4stevel DDI_PROP_DONTPASS, "disk0-scsi-id", -1)) != -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.dsk.disk_pres[0] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.dsk.disk_id[0] = id;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.dsk.disk_pres[0] = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((id = (int)ddi_getprop(DDI_DEV_T_ANY, dnode,
29949e866e40b95795203f3ee46f44a197c946e4stevel DDI_PROP_DONTPASS, "disk1-scsi-id", -1)) != -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.dsk.disk_pres[1] = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.dsk.disk_id[1] = id;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.dsk.disk_pres[1] = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstruct jt_mstr *
29949e866e40b95795203f3ee46f44a197c946e4steveljtag_master_lock(void)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel struct jt_mstr *master = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Now search for the JTAG master and place the addresses for
29949e866e40b95795203f3ee46f44a197c946e4stevel * command into the fhc soft state structure.
29949e866e40b95795203f3ee46f44a197c946e4stevel * Disk board do not have softsp set.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp))
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->softsp && (bdp->softsp->jt_master.is_master == 1)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel master = &bdp->softsp->jt_master;
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_enter(&master->lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (master);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4steveljtag_master_unlock(struct jt_mstr *mstr)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(mutex_owned(&mstr->lock));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mutex_exit(&mstr->lock);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_prime(int first, int count, int incr)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int board;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_evt_t se;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel struct jt_mstr *jtm;
29949e866e40b95795203f3ee46f44a197c946e4stevel int index;
29949e866e40b95795203f3ee46f44a197c946e4stevel int nadded;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fbe->update);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel nadded = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel for (board = first; board < count; board += incr) {
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Search only subset of array. We hold mutex so
29949e866e40b95795203f3ee46f44a197c946e4stevel * noone can add new elements to it.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel index = fhc_b_search(boards.boards, board, 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.last - nadded);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (index == -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_check_size(&boards);
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards[boards.last + 1] =
29949e866e40b95795203f3ee46f44a197c946e4stevel kmem_zalloc(sizeof (fhc_bd_t), KM_SLEEP);
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards[boards.last + 1]->sc.type = UNKNOWN_BOARD;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards[boards.last + 1]->sc.board = board;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.boards[boards.last + 1]->softsp = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.last++;
29949e866e40b95795203f3ee46f44a197c946e4stevel nadded++;
29949e866e40b95795203f3ee46f44a197c946e4stevel boards.sorted = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_check_array(FHC_BOARDS);
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdmax = count - 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Initialize our copy of the disabled board list.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_dlist_init();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fhc_bdlist_lock(-1);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((jtm = jtag_master_lock()) == NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "fhc_bdlist_prime: no jtag master");
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Go through the board list, skipping illegal slots
29949e866e40b95795203f3ee46f44a197c946e4stevel * and initialize each slot.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc = &bdp->sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel board = sc->board;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel se = SYSC_EVT_BD_PRESENT;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sc->type == UNKNOWN_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t fhc_csr;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t fhc_bsr;
29949e866e40b95795203f3ee46f44a197c946e4stevel enum board_type type;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel type = jtag_get_board_type(jtm->jtag_cmd, sc);
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (type) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case -1:
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_sc_evt(sc, SYSC_EVT_BD_EMPTY);
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel case DISK_BOARD:
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Disk boards are handled differently
29949e866e40b95795203f3ee46f44a197c946e4stevel * in that they don't fail POST and have
29949e866e40b95795203f3ee46f44a197c946e4stevel * no fhc attached.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->type = DISK_BOARD;
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) jtag_init_disk_board(jtm->jtag_cmd,
29949e866e40b95795203f3ee46f44a197c946e4stevel board,
29949e866e40b95795203f3ee46f44a197c946e4stevel &fhc_csr, &fhc_bsr);
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_ks_alloc(bdp);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Set the condition to FAILED if POST has
29949e866e40b95795203f3ee46f44a197c946e4stevel * failed. A failed board is physically
29949e866e40b95795203f3ee46f44a197c946e4stevel * present, is not on the disabled list and
29949e866e40b95795203f3ee46f44a197c946e4stevel * is of type UNKNOWN.
29949e866e40b95795203f3ee46f44a197c946e4stevel * NOTE: a non-present board which is
29949e866e40b95795203f3ee46f44a197c946e4stevel * (potentially) on the disabled board
29949e866e40b95795203f3ee46f44a197c946e4stevel * list has been ignored in the empty
29949e866e40b95795203f3ee46f44a197c946e4stevel * slot case.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (fhc_bd_disabled(board)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_ks_alloc(bdp);
29949e866e40b95795203f3ee46f44a197c946e4stevel se = SYSC_EVT_BD_DISABLED;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else
29949e866e40b95795203f3ee46f44a197c946e4stevel se = SYSC_EVT_BD_FAILED;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->type = type;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_sc_evt(sc, se);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Do the disk specific initialization. This routine scans
29949e866e40b95795203f3ee46f44a197c946e4stevel * for all disk boards, so we call it only once.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_dk_init();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel jtag_master_unlock(jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstruct cpu_speed {
29949e866e40b95795203f3ee46f44a197c946e4stevel int cpu_freq;
29949e866e40b95795203f3ee46f44a197c946e4stevel int sram_mode;
29949e866e40b95795203f3ee46f44a197c946e4stevel int system_div;
29949e866e40b95795203f3ee46f44a197c946e4stevel int system_dvd;
29949e866e40b95795203f3ee46f44a197c946e4stevel};
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstruct cpu_speed ultraI_speed_table[] = {
29949e866e40b95795203f3ee46f44a197c946e4stevel { 0, 0, 0, 0},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 143, 1, 2, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 154, 1, 2, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 168, 1, 2, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 182, 1, 3, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 200, 1, 3, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 222, 1, 3, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 250, 1, 3, 1}
29949e866e40b95795203f3ee46f44a197c946e4stevel};
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstruct cpu_speed ultraII_speed_table[] = {
29949e866e40b95795203f3ee46f44a197c946e4stevel { 0, 0, 0, 0},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 360, 2, 2, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 400, 2, 4, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 400, 2, 5, 2},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 248, 2, 3, 2},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 496, 2, 5, 2},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 296, 2, 2, 1},
29949e866e40b95795203f3ee46f44a197c946e4stevel { 336, 2, 2, 1}
29949e866e40b95795203f3ee46f44a197c946e4stevel};
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * set_cpu_info
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * This routine extracts CPU module information used later for
29949e866e40b95795203f3ee46f44a197c946e4stevel * determining hotplug compatibility.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelset_cpu_info(sysc_cfga_stat_t *sc, uint_t fhc_bsr)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel int speed_pins;
29949e866e40b95795203f3ee46f44a197c946e4stevel struct cpu_speed *table;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0; i < 2; i++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.cpu[i].cpu_speed = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.cpu[i].cpu_sram_mode = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!sc->bd.cpu[i].cpu_detected)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel speed_pins = (i == 0) ? CPU_0_PINS(fhc_bsr) :
29949e866e40b95795203f3ee46f44a197c946e4stevel CPU_1_PINS(fhc_bsr);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sc->bd.cpu[i].cpu_compid & CID_REV_MASK) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case ULTRAI_COMPID:
29949e866e40b95795203f3ee46f44a197c946e4stevel table = ultraI_speed_table;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case ULTRAII_COMPID:
29949e866e40b95795203f3ee46f44a197c946e4stevel table = ultraII_speed_table;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "board %d, cpu module %c "
29949e866e40b95795203f3ee46f44a197c946e4stevel "unknown type", sc->board,
29949e866e40b95795203f3ee46f44a197c946e4stevel (i == 0) ? 'A' : 'B');
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.cpu[i].cpu_speed = -1;
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.cpu[i].cpu_speed = table[speed_pins].cpu_freq;
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->bd.cpu[i].cpu_sram_mode = table[speed_pins].sram_mode;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bdlist_scan(sysc_cfga_rstate_t rstate, struct jt_mstr *jtm)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int board;
29949e866e40b95795203f3ee46f44a197c946e4stevel int error;
29949e866e40b95795203f3ee46f44a197c946e4stevel int found = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t fhc_csr;
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t fhc_bsr;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel enum board_type type;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel sc = &bdp->sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel board = sc->board;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Check the boards in EMPTY and DISCONNECTED
29949e866e40b95795203f3ee46f44a197c946e4stevel * states. We need to check a board in the
29949e866e40b95795203f3ee46f44a197c946e4stevel * DISCONNECTED state in case it had been replugged.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sc->in_transition || sc->rstate != rstate)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel else if (sc->rstate == SYSC_CFGA_RSTATE_EMPTY) {
29949e866e40b95795203f3ee46f44a197c946e4stevel type = jtag_get_board_type(jtm->jtag_cmd, sc);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (type == -1)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue; /* no board present */
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->type = type;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else
29949e866e40b95795203f3ee46f44a197c946e4stevel type = sc->type;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (type != UNKNOWN_BOARD)
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) jtag_get_board_info(jtm->jtag_cmd, sc);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel error = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (type == DISK_BOARD)
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Scan the FHC to turn off the board insert
29949e866e40b95795203f3ee46f44a197c946e4stevel * interrupt and modify LEDs based on hotplug
29949e866e40b95795203f3ee46f44a197c946e4stevel * status.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) jtag_init_disk_board(jtm->jtag_cmd, board,
29949e866e40b95795203f3ee46f44a197c946e4stevel &fhc_csr, &fhc_bsr);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel error = jtag_powerdown_board(jtm->jtag_cmd,
29949e866e40b95795203f3ee46f44a197c946e4stevel board, type, &fhc_csr, &fhc_bsr, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (error) {
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_sc_evt(sc, SYSC_EVT_BD_INS_FAILED);
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (fhc_csr & FHC_NOT_BRD_PRES)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (type == CPU_BOARD) {
29949e866e40b95795203f3ee46f44a197c946e4stevel set_cpu_info(sc, fhc_bsr);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_sc_evt(sc, SYSC_EVT_BD_INSERTED);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * A replugged board will still have its kstat info.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!bdp->ksp)
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_ks_alloc(bdp);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel found++;
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (found);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_insert_scan()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct jt_mstr *jtm;
29949e866e40b95795203f3ee46f44a197c946e4stevel int found;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((jtm = jtag_master_lock()) == NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "fhc_bd_insert_scan: no jtag master");
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* first check empty then disconnected */
29949e866e40b95795203f3ee46f44a197c946e4stevel found = fhc_bdlist_scan(SYSC_CFGA_RSTATE_EMPTY, jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!found)
29949e866e40b95795203f3ee46f44a197c946e4stevel found |= fhc_bdlist_scan(SYSC_CFGA_RSTATE_DISCONNECTED, jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!found)
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_WARN, "Could not find hotplugged core system board");
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel jtag_master_unlock(jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (found);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_remove_scan()
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel int poll = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel struct jt_mstr *jtm;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((jtm = jtag_master_lock()) == NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_PANIC, "fhc_bd_remove_scan: no jtag master");
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (bdp = fhc_bd_first(); bdp; bdp = fhc_bd_next(bdp)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sc = &bdp->sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sc->rstate != SYSC_CFGA_RSTATE_DISCONNECTED)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * While there is a board in the disconnected state
29949e866e40b95795203f3ee46f44a197c946e4stevel * continue polling. When the last board is removed,
29949e866e40b95795203f3ee46f44a197c946e4stevel * we will get one last scan.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel poll++;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (sc->in_transition)
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Scan to see if the board is still in.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (jtag_get_board_type(jtm->jtag_cmd, sc) == -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->ksp) {
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_delete(bdp->ksp);
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->ksp = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_sc_evt(sc, SYSC_EVT_BD_REMOVED);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel jtag_master_unlock(jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (poll);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_detachable(int board)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->softsp != NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel return (bdp->flags & BDF_DETACH);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel return (FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_sc_register(void (*f)(void *, sysc_cfga_stat_t *, sysc_evt_t), void *sp)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_evt.update = f;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_evt.soft = sp;
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_update(int board, sysc_evt_t evt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_valid(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * There is a window where this routine might be called
29949e866e40b95795203f3ee46f44a197c946e4stevel * as a result of the environ thread before sysctrl has
29949e866e40b95795203f3ee46f44a197c946e4stevel * attached and registered the callback.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (!(fbe->update))
29949e866e40b95795203f3ee46f44a197c946e4stevel return;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bdlist_lock(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_sc_evt(&bdp->sc, evt);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bdlist_unlock();
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_test(int board, sysc_cfga_pkt_t *pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel uint_t fhc_csr, fhc_bsr;
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel struct jt_mstr *jtm;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_busy(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel sc = &bdp->sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (sc->rstate) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_EMPTY:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "fhc_bd_test: simulate board %d insertion",
29949e866e40b95795203f3ee46f44a197c946e4stevel board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel jtm = jtag_master_lock();
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel jtag_master_unlock(jtm);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) jtag_powerdown_board(jtm->jtag_cmd, board,
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->type, &fhc_csr, &fhc_bsr, TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_RSTATE_DISCONNECTED:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE, "fhc_bd_test: simulate board %d removal",
29949e866e40b95795203f3ee46f44a197c946e4stevel board);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel if (bdp->ksp) {
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_delete(bdp->ksp);
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp->ksp = NULL;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_sc_evt(sc, SYSC_EVT_BD_REMOVED);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel cmn_err(CE_NOTE,
29949e866e40b95795203f3ee46f44a197c946e4stevel "fhc_bd_test: invalid board state: %d", board);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * force a board condition for test purpose
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel/* ARGSUSED */
29949e866e40b95795203f3ee46f44a197c946e4stevelint
29949e866e40b95795203f3ee46f44a197c946e4stevelfhc_bd_test_set_cond(int board, sysc_cfga_pkt_t *sysc_pkt)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel fhc_bd_t *bdp;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_stat_t *sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel sysc_cfga_cond_t cond;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bdlist_locked());
29949e866e40b95795203f3ee46f44a197c946e4stevel ASSERT(fhc_bd_busy(board));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel bdp = fhc_bd(board);
29949e866e40b95795203f3ee46f44a197c946e4stevel sc = &bdp->sc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel cond = (sysc_cfga_cond_t)sysc_pkt->cmd_cfga.arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (cond) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNKNOWN:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_OK:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILING:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_FAILED:
29949e866e40b95795203f3ee46f44a197c946e4stevel case SYSC_CFGA_COND_UNUSABLE:
29949e866e40b95795203f3ee46f44a197c946e4stevel sc->condition = cond;
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel return (EINVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}