kernel: remove unused utsname_set_machine()
[unleashed.git] / usr / src / uts / sun4u / serengeti / io / sbdp_error.c
blob729e1e5f0361f6291a0a4a2697d5a1dd43ba1bbd
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <sys/sunddi.h>
30 #include <sys/note.h>
31 #include <sys/promif.h>
32 #include <sys/sbdp_error.h>
33 #include <sys/sbdp_priv.h>
36 * The purpose if this model is to make it easy to inject error at all
37 * decision making points, such that all code paths can be tested, and
38 * states arrived are expected and recoverable.
40 * Passthru command "inject-error" will be used for injecting
41 * errors. A typical error injection command will look like the
42 * following:
44 * cfgadm -x passthru -o inject-error=func_name:entry_point:value N0.SB0
46 * where "func_name" is the name of the function where error will be
47 * injected, "entry_point" is a number in the function to identify which
48 * decision making point it is that we are injecting error, and "value"
49 * is what we want the check to return. The last field is ignored,
50 * so it can be any valid attachment point.
52 * For example, if we want to inject error at the 3rd entry in function
53 * sbdp_disconnect_cpu (we start counting at 0), we will issue the
54 * following command:
56 * cfgadm -x passthru -o inject-error=sbdp_disconnect_cpu:3:-1 N0.SB0
58 * To clear the error, change the value to 0, or whatever success
59 * corresponds to in the particular function.
61 * cfgadm -x passthru -o inject-error=sbdp_disconnect_cpu:3:0 N0.SB0
63 * Since this command is mainly for debugging, not all illegal options
64 * are rejected. Non-digit strings are accepted for entry point and
65 * value. They will be translated to 0.
67 * Another passthru command "reset-error" is used to clear all errors
68 * that have been injected. The only argument it needs is a valid
69 * attachment point as the last field.
71 * NOTE: Once implemented, the error injection points should remain
72 * relatively stable as QA will be using them for testing.
77 * Variable that controls if error injection should be done or not
79 #ifdef DEBUG
80 uint_t sbdp_do_inject = 1;
83 * Different error injection types that sbdp_ie_type can be
85 #define SBDP_IE_RANDOM 0 /* Returns randomly 0 or -1 */
86 #define SBDP_IE_FAILURE 1 /* Returns -1 */
87 #define SBDP_IE_DEFINED 2 /* Returns value from sbdp_error_matrix */
90 * Variable that controls what type of error injection to do
92 int sbdp_ie_type = SBDP_IE_DEFINED;
95 * Basic return values from sbdp_inject_error
97 #define SUCCESS 0
98 #define FAILURE -1
101 * Maximum number of error injection entry points
103 #define SBDP_IE_MAX_ENTRIES 4
105 typedef struct error_matrix {
106 const char *func_name;
107 uint_t num_entries;
108 int entries[SBDP_IE_MAX_ENTRIES];
109 } error_matrix_t;
111 static error_matrix_t sbdp_error_matrix[] = {
112 { "sbdp_disconnect_cpu", 3, 0, 0, 0, 0 },
113 { "sbdp_connect_cpu", 3, 0, 0, 0, 0 },
114 { "sbdp_cpu_poweron", 2, 0, 0, 0, 0 },
115 { "sbdp_cpu_poweroff", 4, 0, 0, 0, 0 },
116 /* Termination entry, must exist */
117 { NULL, 0, 0, 0, 0, 0 },
120 static int sbdp_func_lookup(const char *func_name);
122 extern int sbdp_strtoi(char *p, char **pos);
125 * sbdp error injector. The argument should be of the following format:
127 * inject_error=func_str:entry_str:value_str
129 * Returns ESBD_INVAL if arg is not of the above format,
130 * or if any of the fields are invalid.
132 * Returns ESBD_NOERROR after setting the correct entry in the error
133 * matrix to the value passed in.
136 sbdp_passthru_inject_error(sbdp_handle_t *hp, void *arg)
138 _NOTE(ARGUNUSED(hp))
140 char *arg_str, *func_str, *entry_str, *value_str;
141 int index, value;
142 size_t len = strlen(arg) + 1;
143 uint_t entry;
144 int rv = ESBD_NOERROR;
145 static char *f = "sbdp_passthru_inject_error";
147 arg_str = kmem_alloc(len, KM_SLEEP);
148 (void) strcpy(arg_str, arg);
151 * Find '=' in the argument. Return ESBD_INVAL if '=' is
152 * not found.
154 if ((func_str = strchr(arg_str, '=')) == NULL) {
155 rv = ESBD_INVAL;
156 goto out;
160 * Now func_str points to '=' in arg_str. Increment the pointer
161 * so it points to the begining of the function string.
162 * Find the first ':' in the argument. Return ESBD_INVAL if
163 * not found.
165 if ((entry_str = strchr(++func_str, ':')) == NULL) {
166 rv = ESBD_INVAL;
167 goto out;
171 * Now entry_str points to the first ':' in arg_str. Set it
172 * to '\0' to NULL terminate func_str. Increment the
173 * pointer so it points to the begining of the entry string.
175 *entry_str++ = '\0';
178 * Now entry_str points to the begining of the entry string.
179 * Find the next ':' in the argument. Return ESBD_INVAL if
180 * ':' is not found.
182 if ((value_str = strchr(entry_str, ':')) == NULL) {
183 rv = ESBD_INVAL;
184 goto out;
188 * Now value_str points to the second ':' in arg_str. Set it
189 * to '\0' to NULL terminate entry_str. Increment the
190 * pointer so it points to the begining of the value string.
191 * The rest of the arg_str is taken as the value string.
193 *value_str++ = '\0';
196 * Find this function in the matrix. Return ESBD_INVAL if
197 * the function name is not found.
199 if ((index = sbdp_func_lookup(func_str)) == -1) {
200 rv = ESBD_INVAL;
201 goto out;
205 * To reduce the amount of code we have to write, we tolerate
206 * non-number input for entry point, and translate it to 0.
208 entry = (uint_t)sbdp_strtoi(entry_str, NULL);
210 if (entry >= sbdp_error_matrix[index].num_entries) {
211 rv = ESBD_INVAL;
212 goto out;
216 * No checking for value. Non-number string will be translated
217 * to 0.
219 value = sbdp_strtoi(value_str, NULL);
221 SBDP_DBG_ERR("%s: index = %d, entry = %d, value = %d\n",
222 f, index, entry, value);
225 * Set value at the right entry.
227 sbdp_error_matrix[index].entries[entry] = value;
229 out:
230 kmem_free(arg_str, len);
231 return (rv);
235 * Reset all entries to 0.
238 sbdp_passthru_reset_error(sbdp_handle_t *hp, void *arg)
240 _NOTE(ARGUNUSED(hp))
241 _NOTE(ARGUNUSED(arg))
243 uint_t i, j;
245 for (i = 0; sbdp_error_matrix[i].func_name != NULL; i++)
246 for (j = 0; j < SBDP_IE_MAX_ENTRIES; j++)
247 sbdp_error_matrix[i].entries[j] = 0;
249 return (ESBD_NOERROR);
253 sbdp_inject_error(const char *func_name, uint_t entry)
255 extern clock_t ddi_get_lbolt(void);
256 int index;
257 int value;
258 static char *f = "sbdp_inject_error";
260 if (sbdp_do_inject == 0)
261 return (SUCCESS);
263 switch (sbdp_ie_type) {
265 case SBDP_IE_RANDOM:
267 * Since we usually only need a binary type of return
268 * value, use lbolt to generate the psuedo random
269 * response.
271 value = (-(int)(ddi_get_lbolt() % 2));
272 break;
274 case SBDP_IE_FAILURE:
275 value = FAILURE;
276 break;
278 case SBDP_IE_DEFINED:
280 * Don't inject error if can't find the function.
282 if ((index = sbdp_func_lookup(func_name)) == -1) {
283 value = SUCCESS;
284 break;
288 * Don't inject error if can't find the entry.
290 if (entry >= sbdp_error_matrix[index].num_entries) {
291 value = SUCCESS;
292 break;
295 value = sbdp_error_matrix[index].entries[entry];
296 break;
298 default:
299 value = SUCCESS;
300 break;
303 if (value != SUCCESS)
304 SBDP_DBG_ERR("%s: function=%s entry=%d value=%d\n",
305 f, func_name, entry, value);
307 return (value);
310 static int
311 sbdp_func_lookup(const char *func_name)
313 int i;
314 const char *name;
317 * Linear search for a match
319 for (i = 0; (name = sbdp_error_matrix[i].func_name) != NULL; i++) {
320 if (strcmp(name, func_name) == 0)
321 return (i);
325 * Function name not found in matrix
327 return (-1);
330 #endif /* DEBUG */