03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/param.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/note.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/promif.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbdp_error.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbdp_priv.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The purpose if this model is to make it easy to inject error at all
03831d35f7499c87d51205817c93e9a8d42c4baestevel * decision making points, such that all code paths can be tested, and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * states arrived are expected and recoverable.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Passthru command "inject-error" will be used for injecting
03831d35f7499c87d51205817c93e9a8d42c4baestevel * errors. A typical error injection command will look like the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * following:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cfgadm -x passthru -o inject-error=func_name:entry_point:value N0.SB0
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * where "func_name" is the name of the function where error will be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * injected, "entry_point" is a number in the function to identify which
03831d35f7499c87d51205817c93e9a8d42c4baestevel * decision making point it is that we are injecting error, and "value"
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is what we want the check to return. The last field is ignored,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so it can be any valid attachment point.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For example, if we want to inject error at the 3rd entry in function
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sbdp_disconnect_cpu (we start counting at 0), we will issue the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * following command:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cfgadm -x passthru -o inject-error=sbdp_disconnect_cpu:3:-1 N0.SB0
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * To clear the error, change the value to 0, or whatever success
03831d35f7499c87d51205817c93e9a8d42c4baestevel * corresponds to in the particular function.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * cfgadm -x passthru -o inject-error=sbdp_disconnect_cpu:3:0 N0.SB0
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Since this command is mainly for debugging, not all illegal options
03831d35f7499c87d51205817c93e9a8d42c4baestevel * are rejected. Non-digit strings are accepted for entry point and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * value. They will be translated to 0.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Another passthru command "reset-error" is used to clear all errors
03831d35f7499c87d51205817c93e9a8d42c4baestevel * that have been injected. The only argument it needs is a valid
03831d35f7499c87d51205817c93e9a8d42c4baestevel * attachment point as the last field.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * NOTE: Once implemented, the error injection points should remain
03831d35f7499c87d51205817c93e9a8d42c4baestevel * relatively stable as QA will be using them for testing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Variable that controls if error injection should be done or not
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baesteveluint_t sbdp_do_inject = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Different error injection types that sbdp_ie_type can be
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SBDP_IE_RANDOM 0 /* Returns randomly 0 or -1 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SBDP_IE_FAILURE 1 /* Returns -1 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SBDP_IE_DEFINED 2 /* Returns value from sbdp_error_matrix */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Variable that controls what type of error injection to do
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint sbdp_ie_type = SBDP_IE_DEFINED;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Basic return values from sbdp_inject_error
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SUCCESS 0
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define FAILURE -1
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Maximum number of error injection entry points
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SBDP_IE_MAX_ENTRIES 4
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baesteveltypedef struct error_matrix {
03831d35f7499c87d51205817c93e9a8d42c4baestevel const char *func_name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t num_entries;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int entries[SBDP_IE_MAX_ENTRIES];
03831d35f7499c87d51205817c93e9a8d42c4baestevel} error_matrix_t;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic error_matrix_t sbdp_error_matrix[] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel { "sbdp_disconnect_cpu", 3, 0, 0, 0, 0 },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { "sbdp_connect_cpu", 3, 0, 0, 0, 0 },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { "sbdp_cpu_poweron", 2, 0, 0, 0, 0 },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { "sbdp_cpu_poweroff", 4, 0, 0, 0, 0 },
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Termination entry, must exist */
03831d35f7499c87d51205817c93e9a8d42c4baestevel { NULL, 0, 0, 0, 0, 0 },
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sbdp_func_lookup(const char *func_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern int sbdp_strtoi(char *p, char **pos);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sbdp error injector. The argument should be of the following format:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * inject_error=func_str:entry_str:value_str
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Returns ESBD_INVAL if arg is not of the above format,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or if any of the fields are invalid.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Returns ESBD_NOERROR after setting the correct entry in the error
03831d35f7499c87d51205817c93e9a8d42c4baestevel * matrix to the value passed in.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_passthru_inject_error(sbdp_handle_t *hp, void *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel _NOTE(ARGUNUSED(hp))
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *arg_str, *func_str, *entry_str, *value_str;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int index, value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t len = strlen(arg) + 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t entry;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = ESBD_NOERROR;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static char *f = "sbdp_passthru_inject_error";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel arg_str = kmem_alloc(len, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strcpy(arg_str, arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find '=' in the argument. Return ESBD_INVAL if '=' is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * not found.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((func_str = strchr(arg_str, '=')) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = ESBD_INVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto out;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now func_str points to '=' in arg_str. Increment the pointer
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so it points to the begining of the function string.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find the first ':' in the argument. Return ESBD_INVAL if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * not found.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((entry_str = strchr(++func_str, ':')) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = ESBD_INVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto out;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now entry_str points to the first ':' in arg_str. Set it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to '\0' to NULL terminate func_str. Increment the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pointer so it points to the begining of the entry string.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel *entry_str++ = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now entry_str points to the begining of the entry string.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find the next ':' in the argument. Return ESBD_INVAL if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ':' is not found.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((value_str = strchr(entry_str, ':')) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = ESBD_INVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto out;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Now value_str points to the second ':' in arg_str. Set it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to '\0' to NULL terminate entry_str. Increment the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pointer so it points to the begining of the value string.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The rest of the arg_str is taken as the value string.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel *value_str++ = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find this function in the matrix. Return ESBD_INVAL if
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the function name is not found.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((index = sbdp_func_lookup(func_str)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = ESBD_INVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto out;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * To reduce the amount of code we have to write, we tolerate
03831d35f7499c87d51205817c93e9a8d42c4baestevel * non-number input for entry point, and translate it to 0.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel entry = (uint_t)sbdp_strtoi(entry_str, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (entry >= sbdp_error_matrix[index].num_entries) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = ESBD_INVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto out;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * No checking for value. Non-number string will be translated
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to 0.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = sbdp_strtoi(value_str, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_ERR("%s: index = %d, entry = %d, value = %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, index, entry, value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Set value at the right entry.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_error_matrix[index].entries[entry] = value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelout:
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(arg_str, len);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Reset all entries to 0.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_passthru_reset_error(sbdp_handle_t *hp, void *arg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel _NOTE(ARGUNUSED(hp))
03831d35f7499c87d51205817c93e9a8d42c4baestevel _NOTE(ARGUNUSED(arg))
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint_t i, j;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; sbdp_error_matrix[i].func_name != NULL; i++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (j = 0; j < SBDP_IE_MAX_ENTRIES; j++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbdp_error_matrix[i].entries[j] = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ESBD_NOERROR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_inject_error(const char *func_name, uint_t entry)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni extern clock_t ddi_get_lbolt(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevel int index;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static char *f = "sbdp_inject_error";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sbdp_do_inject == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (sbdp_ie_type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SBDP_IE_RANDOM:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Since we usually only need a binary type of return
03831d35f7499c87d51205817c93e9a8d42c4baestevel * value, use lbolt to generate the psuedo random
03831d35f7499c87d51205817c93e9a8d42c4baestevel * response.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni value = (-(int)(ddi_get_lbolt() % 2));
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SBDP_IE_FAILURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = FAILURE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SBDP_IE_DEFINED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Don't inject error if can't find the function.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((index = sbdp_func_lookup(func_name)) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Don't inject error if can't find the entry.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (entry >= sbdp_error_matrix[index].num_entries) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = sbdp_error_matrix[index].entries[entry];
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != SUCCESS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel SBDP_DBG_ERR("%s: function=%s entry=%d value=%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, func_name, entry, value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsbdp_func_lookup(const char *func_name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel const char *name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Linear search for a match
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; (name = sbdp_error_matrix[i].func_name) != NULL; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, func_name) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (i);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Function name not found in matrix
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */