1*3db86aabSstevel /*
2*3db86aabSstevel * CDDL HEADER START
3*3db86aabSstevel *
4*3db86aabSstevel * The contents of this file are subject to the terms of the
5*3db86aabSstevel * Common Development and Distribution License, Version 1.0 only
6*3db86aabSstevel * (the "License"). You may not use this file except in compliance
7*3db86aabSstevel * with the License.
8*3db86aabSstevel *
9*3db86aabSstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*3db86aabSstevel * or http://www.opensolaris.org/os/licensing.
11*3db86aabSstevel * See the License for the specific language governing permissions
12*3db86aabSstevel * and limitations under the License.
13*3db86aabSstevel *
14*3db86aabSstevel * When distributing Covered Code, include this CDDL HEADER in each
15*3db86aabSstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*3db86aabSstevel * If applicable, add the following below this CDDL HEADER, with the
17*3db86aabSstevel * fields enclosed by brackets "[]" replaced with your own identifying
18*3db86aabSstevel * information: Portions Copyright [yyyy] [name of copyright owner]
19*3db86aabSstevel *
20*3db86aabSstevel * CDDL HEADER END
21*3db86aabSstevel */
22*3db86aabSstevel /*
23*3db86aabSstevel * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*3db86aabSstevel * Use is subject to license terms.
25*3db86aabSstevel */
26*3db86aabSstevel
27*3db86aabSstevel #pragma ident "%Z%%M% %I% %E% SMI"
28*3db86aabSstevel
29*3db86aabSstevel #include <stddef.h>
30*3db86aabSstevel #include <stdlib.h>
31*3db86aabSstevel #include <unistd.h>
32*3db86aabSstevel #include <ctype.h>
33*3db86aabSstevel #include <fcntl.h>
34*3db86aabSstevel #include <signal.h>
35*3db86aabSstevel #include <string.h>
36*3db86aabSstevel #include <locale.h>
37*3db86aabSstevel #include <errno.h>
38*3db86aabSstevel #include <assert.h>
39*3db86aabSstevel #include <sys/dditypes.h>
40*3db86aabSstevel #include <sys/param.h>
41*3db86aabSstevel #include <sys/obpdefs.h>
42*3db86aabSstevel #include <sys/fhc.h>
43*3db86aabSstevel #include <sys/sysctrl.h>
44*3db86aabSstevel #include <sys/ac.h>
45*3db86aabSstevel #include <sys/spitregs.h>
46*3db86aabSstevel #include <config_admin.h>
47*3db86aabSstevel #include "mema_util.h"
48*3db86aabSstevel #include "mema_test.h"
49*3db86aabSstevel #include "mema_prom.h"
50*3db86aabSstevel
51*3db86aabSstevel #ifdef DEBUG
52*3db86aabSstevel #define DBG (void) printf
53*3db86aabSstevel #define DBG1 (void) printf
54*3db86aabSstevel #define DBG3 (void) printf
55*3db86aabSstevel #define DBG4 (void) printf
56*3db86aabSstevel #else
57*3db86aabSstevel #define DBG(a, b)
58*3db86aabSstevel #define DBG1(a)
59*3db86aabSstevel #define DBG3(a, b, c)
60*3db86aabSstevel #define DBG4(a, b, c, d)
61*3db86aabSstevel #endif
62*3db86aabSstevel
63*3db86aabSstevel #ifndef P_DER_UE
64*3db86aabSstevel /*
65*3db86aabSstevel * <sys/spitregs.h> has these defines inside 'ifdef _KERNEL' at the
66*3db86aabSstevel * time of writing. Re-define here if that is still the case.
67*3db86aabSstevel */
68*3db86aabSstevel
69*3db86aabSstevel #define P_DER_UE 0x00000000000000200ULL /* UE has occurred */
70*3db86aabSstevel #define P_DER_CE 0x00000000000000100ULL /* CE has occurred */
71*3db86aabSstevel #define P_DER_E_SYND 0x000000000000000FFULL /* SYND<7:0>: ECC syndrome */
72*3db86aabSstevel #endif /* ! P_DER_UE */
73*3db86aabSstevel
74*3db86aabSstevel #define DEV_DEBUG
75*3db86aabSstevel #ifdef DEV_DEBUG
76*3db86aabSstevel #include <stdio.h>
77*3db86aabSstevel #include <stdlib.h>
78*3db86aabSstevel
79*3db86aabSstevel static FILE *debug_fp;
80*3db86aabSstevel static int debugging(void);
81*3db86aabSstevel static void dump_ioctl(int, void *);
82*3db86aabSstevel static void dump_ioctl_res(int, void *, int, int);
83*3db86aabSstevel #else /* DEV_DEBUG */
84*3db86aabSstevel #define dump_ioctl(CMD, ARG)
85*3db86aabSstevel #define dump_ioctl_res(CMD, ARG, RET, ERRNO)
86*3db86aabSstevel #endif /* DEV_DEBUG */
87*3db86aabSstevel
88*3db86aabSstevel typedef struct {
89*3db86aabSstevel uint_t board;
90*3db86aabSstevel uint_t bank;
91*3db86aabSstevel } mema_bank_t;
92*3db86aabSstevel
93*3db86aabSstevel static char *mema_opts[] = {
94*3db86aabSstevel #define OPT_BOOT_DISABLE 0
95*3db86aabSstevel "disable-at-boot",
96*3db86aabSstevel #define OPT_BOOT_ENABLE 1
97*3db86aabSstevel "enable-at-boot",
98*3db86aabSstevel #define OPT_TIMEOUT 2
99*3db86aabSstevel "timeout",
100*3db86aabSstevel NULL
101*3db86aabSstevel };
102*3db86aabSstevel
103*3db86aabSstevel #define OPT_NEEDS_VALUE(O) ((O) == OPT_TIMEOUT)
104*3db86aabSstevel
105*3db86aabSstevel #define MAX_OPT_LENGTH (sizeof ("disable-at-boot"))
106*3db86aabSstevel
107*3db86aabSstevel /*
108*3db86aabSstevel * For each function there is an array of opt_control structures giving
109*3db86aabSstevel * the valid options. The array is terminated by an element with the
110*3db86aabSstevel * subopt field set to -1. The group field is used to identify
111*3db86aabSstevel * mutually exclusive options, with zero meaning no grouping.
112*3db86aabSstevel */
113*3db86aabSstevel struct opt_control {
114*3db86aabSstevel int subopt;
115*3db86aabSstevel int group;
116*3db86aabSstevel };
117*3db86aabSstevel
118*3db86aabSstevel /*
119*3db86aabSstevel * Returned set of options.
120*3db86aabSstevel * If the option takes a value, it will be set in 'val'
121*3db86aabSstevel * if the corresponding bit is set in 'bits' is set,
122*3db86aabSstevel * otherwise the pointer in 'val' is undefined.
123*3db86aabSstevel */
124*3db86aabSstevel #define OPT_VAL_ARRAY_SIZE 32 /* # bits in 'bits' */
125*3db86aabSstevel typedef struct {
126*3db86aabSstevel unsigned int bits;
127*3db86aabSstevel char *val[OPT_VAL_ARRAY_SIZE];
128*3db86aabSstevel } option_set_t;
129*3db86aabSstevel
130*3db86aabSstevel #define OPTSET_INIT(S) ((S).bits = 0)
131*3db86aabSstevel #define _OPT_TO_BIT(O) (1 << (O))
132*3db86aabSstevel #define OPTSET_SET_VAL(S, O, V) ((S).bits |= _OPT_TO_BIT(O), \
133*3db86aabSstevel (S).val[(O)] = (V))
134*3db86aabSstevel #define OPTSET_TEST(S, O) (((S).bits & _OPT_TO_BIT(O)) != 0)
135*3db86aabSstevel #define OPTSET_VAL(S, O) ((S).val[(O)])
136*3db86aabSstevel #define OPTSET_IS_EMPTY(S) ((S).bits == 0)
137*3db86aabSstevel
138*3db86aabSstevel static option_set_t process_options(const char *, struct opt_control *,
139*3db86aabSstevel int *, char **);
140*3db86aabSstevel
141*3db86aabSstevel static struct opt_control add_opts[] = {
142*3db86aabSstevel {OPT_BOOT_ENABLE, 1},
143*3db86aabSstevel {OPT_BOOT_DISABLE, 1},
144*3db86aabSstevel {-1, 0}
145*3db86aabSstevel };
146*3db86aabSstevel
147*3db86aabSstevel static struct opt_control del_opts[] = {
148*3db86aabSstevel {OPT_BOOT_ENABLE, 1},
149*3db86aabSstevel {OPT_BOOT_DISABLE, 1},
150*3db86aabSstevel {OPT_TIMEOUT, 2},
151*3db86aabSstevel {-1, 0}
152*3db86aabSstevel };
153*3db86aabSstevel
154*3db86aabSstevel static struct opt_control stat_opts[] = {
155*3db86aabSstevel {OPT_BOOT_ENABLE, 1},
156*3db86aabSstevel {OPT_BOOT_DISABLE, 1},
157*3db86aabSstevel {-1, 0}
158*3db86aabSstevel };
159*3db86aabSstevel
160*3db86aabSstevel #if !defined(TEXT_DOMAIN)
161*3db86aabSstevel #define TEXT_DOMAIN "SYS_TEST"
162*3db86aabSstevel #endif
163*3db86aabSstevel
164*3db86aabSstevel static const char still_testing[] = "bank %s being tested by process %d";
165*3db86aabSstevel static const char no_value[] = "sub-option \"%s\" does not take a value";
166*3db86aabSstevel static const char missing_value[] = "sub-option \"%s\" needs a value";
167*3db86aabSstevel static const char conflict_opt[] = "sub-option \"%s\" conflicts with \"%s\"";
168*3db86aabSstevel static const char unk_subopt[] = "sub-option \"%s\" unknown\n"
169*3db86aabSstevel "choose from: %s";
170*3db86aabSstevel static const char not_valid[] =
171*3db86aabSstevel "sub-option \"%s\" not valid for this operation\n"
172*3db86aabSstevel "choose from: %s";
173*3db86aabSstevel static const char timeout_notnum[] =
174*3db86aabSstevel "timeout value not a positive integer \"%s\"";
175*3db86aabSstevel static const char calloc_fail[] = "memory allocation failed (%d*%d bytes)";
176*3db86aabSstevel static const char unk_test[] = "test \"%s\" unknown\n"
177*3db86aabSstevel "choose from: %s";
178*3db86aabSstevel static const char dup_test[] = "more than one test type specified (\"%s\")";
179*3db86aabSstevel static const char dup_num[] = "option specified more than once (\"%s\")";
180*3db86aabSstevel static const char no_num[] = "invalid number specified for max_errors(\"%s\")";
181*3db86aabSstevel static const char mtest_rw_error[] = "memory test read/write error";
182*3db86aabSstevel static const char mtest_lib_error[] = "memory test library error";
183*3db86aabSstevel static const char dlist_invalid[] = "invalid disabled-memory-list";
184*3db86aabSstevel static const char dlist_write_failed[] = "disabled-memory-list write failed";
185*3db86aabSstevel static const char mtest_unknown_error[] = "unknown memory test error";
186*3db86aabSstevel static const char ap_invalid[] = "invalid attachment point: %s";
187*3db86aabSstevel static const char trans_illegal[] = "illegal transition";
188*3db86aabSstevel static const char open_failed[] = "open failed: %s: %s";
189*3db86aabSstevel static const char mema_help[] = "\nAc specific options:\n";
190*3db86aabSstevel static const char disable_opts[] = "\t-o disable-at-boot\n";
191*3db86aabSstevel static const char enable_opts[] = "\t-o enable-at-boot\n";
192*3db86aabSstevel static const char timeout_opts[] = "\t-o timeout=# (seconds)\n";
193*3db86aabSstevel static const char test_opts[] =
194*3db86aabSstevel "\t-o {quick, normal, extended},[max_errors=#] -t ap_id [ap_id...]\n";
195*3db86aabSstevel static const char private_funcs[] = "\t-x relocate-test ap_id [ap_id...]\n";
196*3db86aabSstevel static const char add_is_disabled[] = "memory is disabled at boot";
197*3db86aabSstevel static const char add_willbe_disabled[] =
198*3db86aabSstevel "memory will be disabled at boot";
199*3db86aabSstevel static const char add_disab_err[] = "cannot get memory disabled status";
200*3db86aabSstevel static const char pfunc_unknown[] = "private function \"%s\" unknown";
201*3db86aabSstevel
202*3db86aabSstevel
203*3db86aabSstevel #define mema_eid(a, b) (((a) << 8) + (b))
204*3db86aabSstevel #define mema_str(i) mema_strs[(i)]
205*3db86aabSstevel
206*3db86aabSstevel #define AC_BK_BUSY 0
207*3db86aabSstevel #define AC_BK_ID 1
208*3db86aabSstevel #define AC_BD_ID 2
209*3db86aabSstevel #define AC_BD_TYPE 3
210*3db86aabSstevel #define AC_BD_STATE 4
211*3db86aabSstevel #define AC_MEM_TEST_ID 5
212*3db86aabSstevel #define AC_MEM_TEST_PAR 6
213*3db86aabSstevel #define AC_MEM_PERM 7
214*3db86aabSstevel #define AC_KPM_CANCELLED 8
215*3db86aabSstevel #define AC_KPM_REFUSED 9
216*3db86aabSstevel #define AC_KPM_SPAN 10
217*3db86aabSstevel #define AC_KPM_DUP 11
218*3db86aabSstevel #define AC_KPM_FAULT 12
219*3db86aabSstevel #define AC_KPM_RESOURCE 13
220*3db86aabSstevel #define AC_KPM_NOTSUP 14
221*3db86aabSstevel #define AC_KPM_NOHANDLES 15
222*3db86aabSstevel #define AC_KPM_NONRELOC 16
223*3db86aabSstevel #define AC_KPM_HANDLE 17
224*3db86aabSstevel #define AC_KPM_BUSY 18
225*3db86aabSstevel #define AC_KPM_NOTVIABLE 19
226*3db86aabSstevel #define AC_KPM_SEQUENCE 20
227*3db86aabSstevel #define AC_KPM_NOWORK 21
228*3db86aabSstevel #define AC_KPM_NOTFINISHED 22
229*3db86aabSstevel #define AC_KPM_NOTRUNNING 23
230*3db86aabSstevel #define AC_VMEM 24
231*3db86aabSstevel #define CMD_MEM_STAT 25
232*3db86aabSstevel #define CMD_MEM_ADD 26
233*3db86aabSstevel #define CMD_MEM_DEL 27
234*3db86aabSstevel #define CMD_MEM_TEST_START 28
235*3db86aabSstevel #define CMD_MEM_TEST_STOP 29
236*3db86aabSstevel #define AC_UNKNOWN 30
237*3db86aabSstevel #define AC_INTR 31
238*3db86aabSstevel #define AC_TIMEOUT 32
239*3db86aabSstevel #define CMD_MEM_RELOCTEST 33
240*3db86aabSstevel #define AC_DEINTLV 34
241*3db86aabSstevel
242*3db86aabSstevel static char *
243*3db86aabSstevel mema_strs[] = {
244*3db86aabSstevel "memory bank busy",
245*3db86aabSstevel "invalid memory bank",
246*3db86aabSstevel "invalid board id",
247*3db86aabSstevel "invalid board type",
248*3db86aabSstevel "invalid board state",
249*3db86aabSstevel "invalid memory test id",
250*3db86aabSstevel "invalid memory test parameter(s)",
251*3db86aabSstevel "no write permission",
252*3db86aabSstevel "memory operation cancelled",
253*3db86aabSstevel "memory operation refused",
254*3db86aabSstevel "memory already in use (add)",
255*3db86aabSstevel "memory span duplicate (delete)",
256*3db86aabSstevel "memory access test failed (add)",
257*3db86aabSstevel "some resource was not available",
258*3db86aabSstevel "operation not supported",
259*3db86aabSstevel "cannot allocate any more handles",
260*3db86aabSstevel "non-relocatable pages in span",
261*3db86aabSstevel "bad handle supplied",
262*3db86aabSstevel "memory in span is being deleted",
263*3db86aabSstevel "VM viability test failed",
264*3db86aabSstevel "function called out of sequence",
265*3db86aabSstevel "no memory to delete",
266*3db86aabSstevel "delete processing not finished",
267*3db86aabSstevel "delete processing not running",
268*3db86aabSstevel "insufficient virtual memory",
269*3db86aabSstevel "memory stat failed: %s",
270*3db86aabSstevel "memory add failed: %s",
271*3db86aabSstevel "memory delete failed: %s",
272*3db86aabSstevel "memory test start failed: %s",
273*3db86aabSstevel "memory test stop failed: %s",
274*3db86aabSstevel "unknown error",
275*3db86aabSstevel "memory delete killed",
276*3db86aabSstevel "memory delete timeout",
277*3db86aabSstevel "memory relocate-test failed: %s",
278*3db86aabSstevel "memory cannot be de-interleaved"
279*3db86aabSstevel };
280*3db86aabSstevel
281*3db86aabSstevel /*
282*3db86aabSstevel * AC_MEM_PERM, EBADF, AC_ERR_MEM_PERM
283*3db86aabSstevel * AC_BK_BUSY, EBUSY, AC_ERR_MEM_BK
284*3db86aabSstevel * AC_KPM_CANCELLED, EINTR, AC_ERR_KPM_CANCELLED
285*3db86aabSstevel * AC_KPM_REFUSED, EINTR, AC_ERR_KPM_REFUSED
286*3db86aabSstevel * AC_BK_ID, EINVAL, AC_ERR_MEM_BK
287*3db86aabSstevel * AC_BD_ID, EINVAL, AC_ERR_BD
288*3db86aabSstevel * AC_BD_TYPE, EINVAL, AC_ERR_BD_TYPE
289*3db86aabSstevel * AC_BD_STATE, EINVAL, AC_ERR_BD_STATE
290*3db86aabSstevel * AC_MEM_TEST_ID, EINVAL, AC_ERR_MEM_TEST
291*3db86aabSstevel * AC_MEM_TEST_PAR, EINVAL, AC_ERR_MEM_TEST_PAR
292*3db86aabSstevel * AC_KPM_SPAN, EINVAL, AC_ERR_KPM_SPAN
293*3db86aabSstevel * AC_KPM_DUP, EINVAL, AC_ERR_KPM_DUP?
294*3db86aabSstevel * AC_KPM_FAULT, EINVAL, AC_ERR_KPM_FAULT
295*3db86aabSstevel * AC_KPM_RESOURCE, EINVAL, AC_ERR_KPM_RESOURCE
296*3db86aabSstevel * AC_KPM_NOTSUP, EINVAL, AC_ERR_KPM_NOTSUP
297*3db86aabSstevel * AC_KPM_NOHANDLES, EINVAL, AC_ERR_KPM_NOHANDLES
298*3db86aabSstevel * AC_KPM_NONRELOC, EINVAL, AC_ERR_KPM_NONRELOC
299*3db86aabSstevel * AC_KPM_HANDLE, EINVAL, AC_ERR_KPM_HANDLE
300*3db86aabSstevel * AC_KPM_BUSY, EINVAL, AC_ERR_KPM_BUSY
301*3db86aabSstevel * AC_KPM_NOTVIABLE, EINVAL, AC_ERR_KPM_NOTVIABLE
302*3db86aabSstevel * AC_KPM_SEQUENCE, EINVAL, AC_ERR_KPM_SEQUENCE
303*3db86aabSstevel * AC_KPM_NOWORK, EINVAL, AC_ERR_KPM_NOWORK
304*3db86aabSstevel * AC_KPM_NOTFINISHED, EINVAL, AC_ERR_KPM_NOTFINISHED
305*3db86aabSstevel * AC_KPM_NOTRUNNING, EINVAL, AC_ERR_KPM_NOTRUNNING
306*3db86aabSstevel * AC_VMEM, ENOMEM, AC_ERR_VMEM
307*3db86aabSstevel * AC_INTR, EINTR, AC_ERR_INTR
308*3db86aabSstevel * AC_TIMEOUT, EINTR, AC_ERR_TIMEOUT
309*3db86aabSstevel * AC_DEINTLV, EINVAL, AC_ERR_MEM_DEINTLV
310*3db86aabSstevel */
311*3db86aabSstevel static int
mema_sid(int err,int acerr)312*3db86aabSstevel mema_sid(int err, int acerr)
313*3db86aabSstevel {
314*3db86aabSstevel if (acerr == AC_ERR_DEFAULT)
315*3db86aabSstevel return (AC_UNKNOWN);
316*3db86aabSstevel
317*3db86aabSstevel switch (mema_eid(err, acerr)) {
318*3db86aabSstevel case mema_eid(EBADF, AC_ERR_MEM_PERM):
319*3db86aabSstevel return (AC_MEM_PERM);
320*3db86aabSstevel case mema_eid(EBUSY, AC_ERR_MEM_BK):
321*3db86aabSstevel return (AC_BK_BUSY);
322*3db86aabSstevel case mema_eid(EINTR, AC_ERR_KPM_CANCELLED):
323*3db86aabSstevel return (AC_KPM_CANCELLED);
324*3db86aabSstevel case mema_eid(EINTR, AC_ERR_KPM_REFUSED):
325*3db86aabSstevel return (AC_KPM_REFUSED);
326*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_MEM_BK):
327*3db86aabSstevel return (AC_BK_ID);
328*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_BD):
329*3db86aabSstevel return (AC_BD_ID);
330*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_BD_TYPE):
331*3db86aabSstevel return (AC_BD_TYPE);
332*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_BD_STATE):
333*3db86aabSstevel return (AC_BD_STATE);
334*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_MEM_TEST):
335*3db86aabSstevel return (AC_MEM_TEST_ID);
336*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_MEM_TEST_PAR):
337*3db86aabSstevel return (AC_MEM_TEST_PAR);
338*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_SPAN):
339*3db86aabSstevel return (AC_KPM_SPAN);
340*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_DUP):
341*3db86aabSstevel return (AC_KPM_DUP);
342*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_FAULT):
343*3db86aabSstevel return (AC_KPM_FAULT);
344*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_RESOURCE):
345*3db86aabSstevel return (AC_KPM_RESOURCE);
346*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTSUP):
347*3db86aabSstevel return (AC_KPM_NOTSUP);
348*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_NOHANDLES):
349*3db86aabSstevel return (AC_KPM_NOHANDLES);
350*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_NONRELOC):
351*3db86aabSstevel return (AC_KPM_NONRELOC);
352*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_HANDLE):
353*3db86aabSstevel return (AC_KPM_HANDLE);
354*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_BUSY):
355*3db86aabSstevel return (AC_KPM_BUSY);
356*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTVIABLE):
357*3db86aabSstevel return (AC_KPM_NOTVIABLE);
358*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_SEQUENCE):
359*3db86aabSstevel return (AC_KPM_SEQUENCE);
360*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_NOWORK):
361*3db86aabSstevel return (AC_KPM_NOWORK);
362*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTFINISHED):
363*3db86aabSstevel return (AC_KPM_NOTFINISHED);
364*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTRUNNING):
365*3db86aabSstevel return (AC_KPM_NOTRUNNING);
366*3db86aabSstevel case mema_eid(ENOMEM, AC_ERR_VMEM):
367*3db86aabSstevel return (AC_VMEM);
368*3db86aabSstevel case mema_eid(EINTR, AC_ERR_INTR):
369*3db86aabSstevel return (AC_INTR);
370*3db86aabSstevel case mema_eid(EINTR, AC_ERR_TIMEOUT):
371*3db86aabSstevel return (AC_TIMEOUT);
372*3db86aabSstevel case mema_eid(EINVAL, AC_ERR_MEM_DEINTLV):
373*3db86aabSstevel return (AC_DEINTLV);
374*3db86aabSstevel default:
375*3db86aabSstevel break;
376*3db86aabSstevel }
377*3db86aabSstevel
378*3db86aabSstevel return (AC_UNKNOWN);
379*3db86aabSstevel }
380*3db86aabSstevel
381*3db86aabSstevel static void
mema_err(ac_cfga_cmd_t * ac,int ret_errno,char ** errstring,int cmd)382*3db86aabSstevel mema_err(ac_cfga_cmd_t *ac, int ret_errno, char **errstring, int cmd)
383*3db86aabSstevel {
384*3db86aabSstevel char *cname = mema_str(cmd);
385*3db86aabSstevel char *syserr;
386*3db86aabSstevel char syserr_num[20];
387*3db86aabSstevel
388*3db86aabSstevel if (ac) {
389*3db86aabSstevel syserr = mema_str(mema_sid(ret_errno, ac->errtype));
390*3db86aabSstevel syserr = dgettext(TEXT_DOMAIN, syserr);
391*3db86aabSstevel } else {
392*3db86aabSstevel syserr = strerror(ret_errno);
393*3db86aabSstevel /* strerror() does its own gettext(). */
394*3db86aabSstevel if (syserr == NULL) {
395*3db86aabSstevel (void) sprintf(syserr_num, "errno=%d", errno);
396*3db86aabSstevel syserr = syserr_num;
397*3db86aabSstevel }
398*3db86aabSstevel }
399*3db86aabSstevel
400*3db86aabSstevel __fmt_errstring(errstring, strlen(syserr),
401*3db86aabSstevel dgettext(TEXT_DOMAIN, cname), syserr);
402*3db86aabSstevel }
403*3db86aabSstevel
404*3db86aabSstevel static void
mema_cmd_init(ac_cfga_cmd_t * ac,void * cmd,char * outputstr,int force)405*3db86aabSstevel mema_cmd_init(ac_cfga_cmd_t *ac, void *cmd, char *outputstr, int force)
406*3db86aabSstevel {
407*3db86aabSstevel (void) memset((void *)ac, 0, sizeof (*ac));
408*3db86aabSstevel
409*3db86aabSstevel ac->errtype = AC_ERR_DEFAULT;
410*3db86aabSstevel ac->private = cmd;
411*3db86aabSstevel ac->force = force;
412*3db86aabSstevel ac->outputstr = outputstr;
413*3db86aabSstevel
414*3db86aabSstevel (void) memset((void *)outputstr, 0, AC_OUTPUT_LEN);
415*3db86aabSstevel }
416*3db86aabSstevel
417*3db86aabSstevel static int
ap_bk_idx(const char * ap_id)418*3db86aabSstevel ap_bk_idx(const char *ap_id)
419*3db86aabSstevel {
420*3db86aabSstevel int id;
421*3db86aabSstevel char *s;
422*3db86aabSstevel static char *bank = "bank";
423*3db86aabSstevel
424*3db86aabSstevel DBG("ap_bk_idx(%s)\n", ap_id);
425*3db86aabSstevel
426*3db86aabSstevel if ((s = strstr(ap_id, bank)) == NULL)
427*3db86aabSstevel return (-1);
428*3db86aabSstevel else {
429*3db86aabSstevel int n;
430*3db86aabSstevel
431*3db86aabSstevel s += strlen(bank);
432*3db86aabSstevel n = strlen(s);
433*3db86aabSstevel
434*3db86aabSstevel DBG3("ap_bk_idx: s=%s, n=%d\n", s, n);
435*3db86aabSstevel
436*3db86aabSstevel if ((n != 1) || !isdigit(s[0]))
437*3db86aabSstevel return (-1);
438*3db86aabSstevel }
439*3db86aabSstevel
440*3db86aabSstevel id = atoi(s);
441*3db86aabSstevel
442*3db86aabSstevel if (id < 0 || id > 1)
443*3db86aabSstevel return (-1);
444*3db86aabSstevel
445*3db86aabSstevel DBG3("ap_bk_idx(%s)=%d\n", s, id);
446*3db86aabSstevel
447*3db86aabSstevel return (id);
448*3db86aabSstevel }
449*3db86aabSstevel
450*3db86aabSstevel static cfga_err_t
ap_stat(const char * bank_spec,int * fdp,mema_bank_t * bkp,ac_stat_t * stp,char ** errstring)451*3db86aabSstevel ap_stat(
452*3db86aabSstevel const char *bank_spec,
453*3db86aabSstevel int *fdp,
454*3db86aabSstevel mema_bank_t *bkp,
455*3db86aabSstevel ac_stat_t *stp,
456*3db86aabSstevel char **errstring)
457*3db86aabSstevel {
458*3db86aabSstevel int fd;
459*3db86aabSstevel int ret, ret_errno;
460*3db86aabSstevel int bank;
461*3db86aabSstevel mema_bank_t bk;
462*3db86aabSstevel ac_stat_t stat;
463*3db86aabSstevel ac_cfga_cmd_t cmd;
464*3db86aabSstevel char outputstr[AC_OUTPUT_LEN];
465*3db86aabSstevel
466*3db86aabSstevel if ((bank = ap_bk_idx(bank_spec)) == -1) {
467*3db86aabSstevel __fmt_errstring(errstring, strlen(bank_spec),
468*3db86aabSstevel dgettext(TEXT_DOMAIN, ap_invalid), bank_spec);
469*3db86aabSstevel return (CFGA_ERROR);
470*3db86aabSstevel }
471*3db86aabSstevel
472*3db86aabSstevel bk.bank = bank;
473*3db86aabSstevel
474*3db86aabSstevel if ((fd = open(bank_spec, ((fdp != NULL) ? O_RDWR : O_RDONLY), 0)) ==
475*3db86aabSstevel -1) {
476*3db86aabSstevel char *syserr;
477*3db86aabSstevel char syserr_num[20];
478*3db86aabSstevel
479*3db86aabSstevel syserr = strerror(errno);
480*3db86aabSstevel if (syserr == NULL) {
481*3db86aabSstevel (void) sprintf(syserr_num, "errno=%d", errno);
482*3db86aabSstevel syserr = syserr_num;
483*3db86aabSstevel }
484*3db86aabSstevel __fmt_errstring(errstring, strlen(syserr) +
485*3db86aabSstevel strlen(bank_spec),
486*3db86aabSstevel dgettext(TEXT_DOMAIN, open_failed), bank_spec, syserr);
487*3db86aabSstevel return (CFGA_ERROR);
488*3db86aabSstevel }
489*3db86aabSstevel
490*3db86aabSstevel mema_cmd_init(&cmd, &stat, outputstr, 0);
491*3db86aabSstevel dump_ioctl(AC_MEM_STAT, NULL);
492*3db86aabSstevel ret = ioctl(fd, AC_MEM_STAT, &cmd);
493*3db86aabSstevel ret_errno = errno;
494*3db86aabSstevel dump_ioctl_res(AC_MEM_STAT, &stat, ret, ret_errno);
495*3db86aabSstevel
496*3db86aabSstevel if (ret == -1) {
497*3db86aabSstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_STAT);
498*3db86aabSstevel (void) close(fd);
499*3db86aabSstevel return (CFGA_ERROR);
500*3db86aabSstevel }
501*3db86aabSstevel
502*3db86aabSstevel if (fdp)
503*3db86aabSstevel *fdp = fd;
504*3db86aabSstevel else
505*3db86aabSstevel (void) close(fd);
506*3db86aabSstevel
507*3db86aabSstevel if (stp)
508*3db86aabSstevel *stp = stat;
509*3db86aabSstevel
510*3db86aabSstevel if (bkp) {
511*3db86aabSstevel bkp->bank = bk.bank;
512*3db86aabSstevel bkp->board = stat.board;
513*3db86aabSstevel }
514*3db86aabSstevel
515*3db86aabSstevel return (CFGA_OK);
516*3db86aabSstevel }
517*3db86aabSstevel
518*3db86aabSstevel static void
set_disabled_bits(mema_disabled_t * dp,int value)519*3db86aabSstevel set_disabled_bits(mema_disabled_t *dp, int value)
520*3db86aabSstevel {
521*3db86aabSstevel if (value == 0)
522*3db86aabSstevel *dp &= ~PROM_MEMORY_DISABLED;
523*3db86aabSstevel else
524*3db86aabSstevel *dp |= PROM_MEMORY_DISABLED;
525*3db86aabSstevel }
526*3db86aabSstevel
527*3db86aabSstevel static void
set_present_bits(mema_disabled_t * dp,ac_stat_t * asp)528*3db86aabSstevel set_present_bits(mema_disabled_t *dp, ac_stat_t *asp)
529*3db86aabSstevel {
530*3db86aabSstevel if (asp->ostate == SYSC_CFGA_OSTATE_CONFIGURED)
531*3db86aabSstevel *dp |= PROM_MEMORY_PRESENT;
532*3db86aabSstevel else
533*3db86aabSstevel *dp &= ~PROM_MEMORY_DISABLED;
534*3db86aabSstevel }
535*3db86aabSstevel
536*3db86aabSstevel static cfga_err_t
prom_do_options(option_set_t do_option,int board,ac_stat_t * asp,char ** errstring)537*3db86aabSstevel prom_do_options(
538*3db86aabSstevel option_set_t do_option,
539*3db86aabSstevel int board,
540*3db86aabSstevel ac_stat_t *asp,
541*3db86aabSstevel char **errstring)
542*3db86aabSstevel {
543*3db86aabSstevel cfga_err_t ret;
544*3db86aabSstevel mema_disabled_t disab;
545*3db86aabSstevel
546*3db86aabSstevel if (!prom_read_disabled_list(&disab, board))
547*3db86aabSstevel return (CFGA_ERROR);
548*3db86aabSstevel
549*3db86aabSstevel set_present_bits(&disab, asp);
550*3db86aabSstevel
551*3db86aabSstevel ret = CFGA_OK;
552*3db86aabSstevel
553*3db86aabSstevel if (OPTSET_TEST(do_option, OPT_BOOT_ENABLE)) {
554*3db86aabSstevel set_disabled_bits(&disab, 0);
555*3db86aabSstevel if (!prom_viable_disabled_list(&disab)) {
556*3db86aabSstevel __fmt_errstring(errstring, 0,
557*3db86aabSstevel dgettext(TEXT_DOMAIN, dlist_invalid));
558*3db86aabSstevel ret = CFGA_ERROR;
559*3db86aabSstevel } else if (!prom_write_disabled_list(&disab, board)) {
560*3db86aabSstevel __fmt_errstring(errstring, 0,
561*3db86aabSstevel dgettext(TEXT_DOMAIN, dlist_write_failed));
562*3db86aabSstevel ret = CFGA_ERROR;
563*3db86aabSstevel }
564*3db86aabSstevel } else if (OPTSET_TEST(do_option, OPT_BOOT_DISABLE)) {
565*3db86aabSstevel set_disabled_bits(&disab, 1);
566*3db86aabSstevel if (!prom_viable_disabled_list(&disab)) {
567*3db86aabSstevel __fmt_errstring(errstring, 0,
568*3db86aabSstevel dgettext(TEXT_DOMAIN, dlist_invalid));
569*3db86aabSstevel ret = CFGA_ERROR;
570*3db86aabSstevel } else if (!prom_write_disabled_list(&disab, board)) {
571*3db86aabSstevel __fmt_errstring(errstring, 0,
572*3db86aabSstevel dgettext(TEXT_DOMAIN, dlist_write_failed));
573*3db86aabSstevel ret = CFGA_ERROR;
574*3db86aabSstevel }
575*3db86aabSstevel }
576*3db86aabSstevel
577*3db86aabSstevel return (ret);
578*3db86aabSstevel }
579*3db86aabSstevel
580*3db86aabSstevel static cfga_err_t
mema_add(const char * bank_spec,const char * options,char ** errstring,int force)581*3db86aabSstevel mema_add(
582*3db86aabSstevel const char *bank_spec,
583*3db86aabSstevel const char *options,
584*3db86aabSstevel char **errstring,
585*3db86aabSstevel int force)
586*3db86aabSstevel {
587*3db86aabSstevel mema_bank_t bk;
588*3db86aabSstevel int fd, ret, ret_errno;
589*3db86aabSstevel option_set_t do_option;
590*3db86aabSstevel ac_cfga_cmd_t cmd;
591*3db86aabSstevel ac_stat_t stat;
592*3db86aabSstevel char outputstr[AC_OUTPUT_LEN];
593*3db86aabSstevel
594*3db86aabSstevel ret = 0;
595*3db86aabSstevel do_option = process_options(options, add_opts, &ret, errstring);
596*3db86aabSstevel if (ret != 0) {
597*3db86aabSstevel return (ret);
598*3db86aabSstevel }
599*3db86aabSstevel
600*3db86aabSstevel ret = ap_stat(bank_spec, &fd, &bk, &stat, errstring);
601*3db86aabSstevel if (ret != CFGA_OK)
602*3db86aabSstevel return (ret);
603*3db86aabSstevel
604*3db86aabSstevel
605*3db86aabSstevel if (stat.rstate != SYSC_CFGA_RSTATE_CONNECTED ||
606*3db86aabSstevel stat.ostate != SYSC_CFGA_OSTATE_UNCONFIGURED) {
607*3db86aabSstevel __fmt_errstring(errstring, 0,
608*3db86aabSstevel dgettext(TEXT_DOMAIN, trans_illegal));
609*3db86aabSstevel (void) close(fd);
610*3db86aabSstevel return (CFGA_ERROR);
611*3db86aabSstevel }
612*3db86aabSstevel
613*3db86aabSstevel if (!force) {
614*3db86aabSstevel mema_disabled_t disab;
615*3db86aabSstevel
616*3db86aabSstevel if (prom_read_disabled_list(&disab, bk.board)) {
617*3db86aabSstevel if (disab != 0 &&
618*3db86aabSstevel !OPTSET_TEST(do_option, OPT_BOOT_ENABLE)) {
619*3db86aabSstevel __fmt_errstring(errstring, 0,
620*3db86aabSstevel dgettext(TEXT_DOMAIN, add_is_disabled));
621*3db86aabSstevel (void) close(fd);
622*3db86aabSstevel return (CFGA_ERROR);
623*3db86aabSstevel }
624*3db86aabSstevel if (disab == 0 &&
625*3db86aabSstevel OPTSET_TEST(do_option, OPT_BOOT_DISABLE)) {
626*3db86aabSstevel __fmt_errstring(errstring, 0,
627*3db86aabSstevel dgettext(TEXT_DOMAIN, add_willbe_disabled));
628*3db86aabSstevel (void) close(fd);
629*3db86aabSstevel return (CFGA_ERROR);
630*3db86aabSstevel }
631*3db86aabSstevel } else {
632*3db86aabSstevel __fmt_errstring(errstring, 0,
633*3db86aabSstevel dgettext(TEXT_DOMAIN, add_disab_err));
634*3db86aabSstevel (void) close(fd);
635*3db86aabSstevel return (CFGA_ERROR);
636*3db86aabSstevel }
637*3db86aabSstevel }
638*3db86aabSstevel
639*3db86aabSstevel mema_cmd_init(&cmd, NULL, outputstr, force);
640*3db86aabSstevel dump_ioctl(AC_MEM_CONFIGURE, NULL);
641*3db86aabSstevel ret = ioctl(fd, AC_MEM_CONFIGURE, &cmd);
642*3db86aabSstevel ret_errno = errno;
643*3db86aabSstevel dump_ioctl_res(AC_MEM_CONFIGURE, NULL, ret, ret_errno);
644*3db86aabSstevel (void) close(fd);
645*3db86aabSstevel
646*3db86aabSstevel if (ret == -1) {
647*3db86aabSstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_ADD);
648*3db86aabSstevel return (CFGA_ERROR);
649*3db86aabSstevel }
650*3db86aabSstevel
651*3db86aabSstevel ret = prom_do_options(do_option, bk.board, &stat, errstring);
652*3db86aabSstevel
653*3db86aabSstevel return (ret);
654*3db86aabSstevel }
655*3db86aabSstevel
656*3db86aabSstevel static cfga_err_t
mema_delete(const char * bank_spec,const char * options,char ** errstring,int force)657*3db86aabSstevel mema_delete(
658*3db86aabSstevel const char *bank_spec,
659*3db86aabSstevel const char *options,
660*3db86aabSstevel char **errstring,
661*3db86aabSstevel int force)
662*3db86aabSstevel {
663*3db86aabSstevel mema_bank_t bk;
664*3db86aabSstevel int fd, ret, ret_errno;
665*3db86aabSstevel option_set_t do_option;
666*3db86aabSstevel ac_cfga_cmd_t cmd;
667*3db86aabSstevel ac_stat_t stat;
668*3db86aabSstevel char outputstr[AC_OUTPUT_LEN];
669*3db86aabSstevel int timeout_secs = -1; /* Init to 'use default'. */
670*3db86aabSstevel
671*3db86aabSstevel ret = 0;
672*3db86aabSstevel do_option = process_options(options, del_opts, &ret, errstring);
673*3db86aabSstevel if (ret != 0) {
674*3db86aabSstevel return (ret);
675*3db86aabSstevel }
676*3db86aabSstevel
677*3db86aabSstevel if (OPTSET_TEST(do_option, OPT_TIMEOUT)) {
678*3db86aabSstevel char *to_val;
679*3db86aabSstevel char *ep;
680*3db86aabSstevel
681*3db86aabSstevel to_val = OPTSET_VAL(do_option, OPT_TIMEOUT);
682*3db86aabSstevel timeout_secs = (int)strtol(to_val, &ep, 10);
683*3db86aabSstevel if (*ep != '\0' || ep == to_val || timeout_secs < 0) {
684*3db86aabSstevel __fmt_errstring(errstring, strlen(to_val),
685*3db86aabSstevel dgettext(TEXT_DOMAIN, timeout_notnum), to_val);
686*3db86aabSstevel return (CFGA_ERROR);
687*3db86aabSstevel }
688*3db86aabSstevel }
689*3db86aabSstevel
690*3db86aabSstevel ret = ap_stat(bank_spec, &fd, &bk, &stat, errstring);
691*3db86aabSstevel if (ret != CFGA_OK)
692*3db86aabSstevel return (ret);
693*3db86aabSstevel
694*3db86aabSstevel if (stat.rstate != SYSC_CFGA_RSTATE_CONNECTED ||
695*3db86aabSstevel stat.ostate != SYSC_CFGA_OSTATE_CONFIGURED) {
696*3db86aabSstevel __fmt_errstring(errstring, 0,
697*3db86aabSstevel dgettext(TEXT_DOMAIN, trans_illegal));
698*3db86aabSstevel (void) close(fd);
699*3db86aabSstevel return (CFGA_ERROR);
700*3db86aabSstevel }
701*3db86aabSstevel
702*3db86aabSstevel mema_cmd_init(&cmd, NULL, outputstr, force);
703*3db86aabSstevel cmd.arg = timeout_secs;
704*3db86aabSstevel dump_ioctl(AC_MEM_UNCONFIGURE, NULL);
705*3db86aabSstevel ret = ioctl(fd, AC_MEM_UNCONFIGURE, &cmd);
706*3db86aabSstevel ret_errno = errno;
707*3db86aabSstevel dump_ioctl_res(AC_MEM_UNCONFIGURE, NULL, ret, ret_errno);
708*3db86aabSstevel (void) close(fd);
709*3db86aabSstevel
710*3db86aabSstevel if (ret == -1) {
711*3db86aabSstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_DEL);
712*3db86aabSstevel return (CFGA_ERROR);
713*3db86aabSstevel }
714*3db86aabSstevel
715*3db86aabSstevel ret = prom_do_options(do_option, bk.board, &stat, errstring);
716*3db86aabSstevel
717*3db86aabSstevel return (ret);
718*3db86aabSstevel }
719*3db86aabSstevel
720*3db86aabSstevel /*ARGSUSED*/
721*3db86aabSstevel cfga_err_t
cfga_change_state(cfga_cmd_t state_change_cmd,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)722*3db86aabSstevel cfga_change_state(
723*3db86aabSstevel cfga_cmd_t state_change_cmd,
724*3db86aabSstevel const char *ap_id,
725*3db86aabSstevel const char *options,
726*3db86aabSstevel struct cfga_confirm *confp,
727*3db86aabSstevel struct cfga_msg *msgp,
728*3db86aabSstevel char **errstring,
729*3db86aabSstevel cfga_flags_t flags)
730*3db86aabSstevel {
731*3db86aabSstevel int force;
732*3db86aabSstevel cfga_err_t rc;
733*3db86aabSstevel
734*3db86aabSstevel if (errstring != NULL)
735*3db86aabSstevel *errstring = NULL;
736*3db86aabSstevel
737*3db86aabSstevel force = flags & CFGA_FLAG_FORCE;
738*3db86aabSstevel
739*3db86aabSstevel switch (state_change_cmd) {
740*3db86aabSstevel case CFGA_CMD_CONFIGURE:
741*3db86aabSstevel rc = mema_add(ap_id, options, errstring, force);
742*3db86aabSstevel break;
743*3db86aabSstevel
744*3db86aabSstevel case CFGA_CMD_UNCONFIGURE:
745*3db86aabSstevel rc = mema_delete(ap_id, options, errstring, force);
746*3db86aabSstevel break;
747*3db86aabSstevel
748*3db86aabSstevel default:
749*3db86aabSstevel rc = CFGA_OPNOTSUPP;
750*3db86aabSstevel break;
751*3db86aabSstevel }
752*3db86aabSstevel
753*3db86aabSstevel return (rc);
754*3db86aabSstevel }
755*3db86aabSstevel
756*3db86aabSstevel /*ARGSUSED*/
757*3db86aabSstevel cfga_err_t
cfga_private_func(const char * function,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)758*3db86aabSstevel cfga_private_func(
759*3db86aabSstevel const char *function,
760*3db86aabSstevel const char *ap_id,
761*3db86aabSstevel const char *options,
762*3db86aabSstevel struct cfga_confirm *confp,
763*3db86aabSstevel struct cfga_msg *msgp,
764*3db86aabSstevel char **errstring,
765*3db86aabSstevel cfga_flags_t flags)
766*3db86aabSstevel {
767*3db86aabSstevel mema_bank_t bk;
768*3db86aabSstevel ac_stat_t stat;
769*3db86aabSstevel int fd, ret, ret_errno;
770*3db86aabSstevel ac_cfga_cmd_t cmd;
771*3db86aabSstevel char outputstr[AC_OUTPUT_LEN];
772*3db86aabSstevel
773*3db86aabSstevel if (errstring != NULL)
774*3db86aabSstevel *errstring = NULL;
775*3db86aabSstevel
776*3db86aabSstevel ret = ap_stat(ap_id, &fd, &bk, &stat, errstring);
777*3db86aabSstevel if (ret != CFGA_OK)
778*3db86aabSstevel return (ret);
779*3db86aabSstevel
780*3db86aabSstevel if (strcmp(function, "relocate-test") == 0) {
781*3db86aabSstevel struct ac_memx_relocate_stats rstat;
782*3db86aabSstevel
783*3db86aabSstevel mema_cmd_init(&cmd, NULL, outputstr,
784*3db86aabSstevel (flags & CFGA_FLAG_FORCE));
785*3db86aabSstevel cmd.arg = AC_MEMX_RELOCATE_ALL;
786*3db86aabSstevel cmd.private = &rstat;
787*3db86aabSstevel (void) memset((void *)&rstat, 0, sizeof (rstat));
788*3db86aabSstevel dump_ioctl(AC_MEM_EXERCISE, &cmd);
789*3db86aabSstevel ret = ioctl(fd, AC_MEM_EXERCISE, &cmd);
790*3db86aabSstevel ret_errno = errno;
791*3db86aabSstevel dump_ioctl_res(AC_MEM_EXERCISE, &cmd, ret, ret_errno);
792*3db86aabSstevel (void) close(fd);
793*3db86aabSstevel
794*3db86aabSstevel if (ret == -1) {
795*3db86aabSstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_RELOCTEST);
796*3db86aabSstevel return (CFGA_ERROR);
797*3db86aabSstevel }
798*3db86aabSstevel return (CFGA_OK);
799*3db86aabSstevel }
800*3db86aabSstevel
801*3db86aabSstevel __fmt_errstring(errstring, strlen(function),
802*3db86aabSstevel dgettext(TEXT_DOMAIN, pfunc_unknown), function);
803*3db86aabSstevel
804*3db86aabSstevel return (CFGA_ERROR);
805*3db86aabSstevel }
806*3db86aabSstevel
807*3db86aabSstevel static int
mtest_run(int fd,int test_fun,mema_bank_t * abkp,struct cfga_msg * msgp,char ** errstring,ulong_t max_errors)808*3db86aabSstevel mtest_run(
809*3db86aabSstevel int fd,
810*3db86aabSstevel int test_fun,
811*3db86aabSstevel mema_bank_t *abkp,
812*3db86aabSstevel struct cfga_msg *msgp,
813*3db86aabSstevel char **errstring,
814*3db86aabSstevel ulong_t max_errors)
815*3db86aabSstevel {
816*3db86aabSstevel ac_mem_test_start_t test_start;
817*3db86aabSstevel ac_mem_test_stop_t test_stop;
818*3db86aabSstevel struct mtest_handle handle;
819*3db86aabSstevel int ret, ret_errno;
820*3db86aabSstevel int res;
821*3db86aabSstevel ac_cfga_cmd_t cmd;
822*3db86aabSstevel char outputstr[AC_OUTPUT_LEN];
823*3db86aabSstevel
824*3db86aabSstevel (void) memset((void *)&test_start, 0, sizeof (test_start));
825*3db86aabSstevel mema_cmd_init(&cmd, &test_start, outputstr, 0);
826*3db86aabSstevel dump_ioctl(AC_MEM_TEST_START, &test_start);
827*3db86aabSstevel ret = ioctl(fd, AC_MEM_TEST_START, &cmd);
828*3db86aabSstevel ret_errno = errno;
829*3db86aabSstevel dump_ioctl_res(AC_MEM_TEST_START, &test_start, ret, ret_errno);
830*3db86aabSstevel
831*3db86aabSstevel if (ret == -1) {
832*3db86aabSstevel if (ret_errno == ENOTSUP) {
833*3db86aabSstevel mema_err(&cmd, ret_errno, errstring,
834*3db86aabSstevel CMD_MEM_TEST_START);
835*3db86aabSstevel return (CFGA_OPNOTSUPP);
836*3db86aabSstevel }
837*3db86aabSstevel if (ret_errno == EBUSY && test_start.tester_pid > 0) {
838*3db86aabSstevel /*
839*3db86aabSstevel * Bank appears to be being tested. Check that
840*3db86aabSstevel * process 'tester_pid' is still running.
841*3db86aabSstevel */
842*3db86aabSstevel if (kill(test_start.tester_pid, 0) != -1 ||
843*3db86aabSstevel errno != ESRCH) {
844*3db86aabSstevel cfga_ap_log_id_t bname;
845*3db86aabSstevel
846*3db86aabSstevel /* Process still exists. */
847*3db86aabSstevel (void) sprintf(bname, "board %d bank%d",
848*3db86aabSstevel abkp->board, abkp->bank);
849*3db86aabSstevel __fmt_errstring(errstring, strlen(bname),
850*3db86aabSstevel dgettext(TEXT_DOMAIN, still_testing),
851*3db86aabSstevel bname, test_start.tester_pid);
852*3db86aabSstevel return (CFGA_ERROR);
853*3db86aabSstevel }
854*3db86aabSstevel /*
855*3db86aabSstevel * Do a test stop and re-try the start.
856*3db86aabSstevel */
857*3db86aabSstevel (void) memset((void *)&test_stop, 0,
858*3db86aabSstevel sizeof (test_stop));
859*3db86aabSstevel test_stop.handle = test_start.handle;
860*3db86aabSstevel test_stop.condition = SYSC_CFGA_COND_UNKNOWN;
861*3db86aabSstevel mema_cmd_init(&cmd, &test_stop, outputstr, 0);
862*3db86aabSstevel dump_ioctl(AC_MEM_TEST_STOP, &test_stop);
863*3db86aabSstevel ret = ioctl(fd, AC_MEM_TEST_STOP, &cmd);
864*3db86aabSstevel ret_errno = errno;
865*3db86aabSstevel dump_ioctl_res(AC_MEM_TEST_STOP, &test_stop,
866*3db86aabSstevel ret, ret_errno);
867*3db86aabSstevel /*
868*3db86aabSstevel * Ignore test stop error processing and re-try the
869*3db86aabSstevel * start. The error return will be derived from the
870*3db86aabSstevel * result of start.
871*3db86aabSstevel */
872*3db86aabSstevel (void) memset((void *)&test_start, 0,
873*3db86aabSstevel sizeof (test_start));
874*3db86aabSstevel mema_cmd_init(&cmd, &test_start, outputstr, 0);
875*3db86aabSstevel dump_ioctl(AC_MEM_TEST_START, &test_start);
876*3db86aabSstevel ret = ioctl(fd, AC_MEM_TEST_START, &cmd);
877*3db86aabSstevel ret_errno = errno;
878*3db86aabSstevel dump_ioctl_res(AC_MEM_TEST_START, &test_start,
879*3db86aabSstevel ret, ret_errno);
880*3db86aabSstevel }
881*3db86aabSstevel /* Test return code again to cover the case of a re-try. */
882*3db86aabSstevel if (ret == -1) {
883*3db86aabSstevel mema_err(&cmd, ret_errno, errstring,
884*3db86aabSstevel CMD_MEM_TEST_START);
885*3db86aabSstevel return (CFGA_ERROR);
886*3db86aabSstevel }
887*3db86aabSstevel }
888*3db86aabSstevel (void) memset((void *)&handle, 0, sizeof (handle));
889*3db86aabSstevel handle.fd = fd;
890*3db86aabSstevel handle.drvhandle = (void *)&test_start;
891*3db86aabSstevel handle.msgp = msgp;
892*3db86aabSstevel handle.bank_size = test_start.bank_size;
893*3db86aabSstevel handle.page_size = test_start.page_size;
894*3db86aabSstevel handle.line_size = test_start.line_size;
895*3db86aabSstevel handle.lines_per_page = test_start.page_size / test_start.line_size;
896*3db86aabSstevel handle.condition = CFGA_COND_UNKNOWN;
897*3db86aabSstevel handle.max_errors = max_errors;
898*3db86aabSstevel
899*3db86aabSstevel res = (*mtest_table[test_fun].test_func)(&handle);
900*3db86aabSstevel
901*3db86aabSstevel mtest_deallocate_buf_all(&handle);
902*3db86aabSstevel
903*3db86aabSstevel /*
904*3db86aabSstevel * Convert memory test code to MEMA_ code.
905*3db86aabSstevel */
906*3db86aabSstevel switch (res) {
907*3db86aabSstevel case MTEST_DONE:
908*3db86aabSstevel res = CFGA_OK;
909*3db86aabSstevel break;
910*3db86aabSstevel case MTEST_LIB_ERROR:
911*3db86aabSstevel __fmt_errstring(errstring, 0, dgettext(TEXT_DOMAIN,
912*3db86aabSstevel mtest_lib_error));
913*3db86aabSstevel res = CFGA_ERROR;
914*3db86aabSstevel break;
915*3db86aabSstevel case MTEST_DEV_ERROR:
916*3db86aabSstevel __fmt_errstring(errstring, 0, dgettext(TEXT_DOMAIN,
917*3db86aabSstevel mtest_rw_error));
918*3db86aabSstevel res = CFGA_ERROR;
919*3db86aabSstevel break;
920*3db86aabSstevel default:
921*3db86aabSstevel __fmt_errstring(errstring, 0, dgettext(TEXT_DOMAIN,
922*3db86aabSstevel mtest_unknown_error));
923*3db86aabSstevel res = CFGA_ERROR;
924*3db86aabSstevel assert(0);
925*3db86aabSstevel break;
926*3db86aabSstevel }
927*3db86aabSstevel
928*3db86aabSstevel (void) memset((void *)&test_stop, 0, sizeof (test_stop));
929*3db86aabSstevel test_stop.handle = test_start.handle;
930*3db86aabSstevel switch (handle.condition) {
931*3db86aabSstevel case CFGA_COND_OK:
932*3db86aabSstevel test_stop.condition = SYSC_CFGA_COND_OK;
933*3db86aabSstevel break;
934*3db86aabSstevel case CFGA_COND_FAILING:
935*3db86aabSstevel test_stop.condition = SYSC_CFGA_COND_FAILING;
936*3db86aabSstevel break;
937*3db86aabSstevel case CFGA_COND_FAILED:
938*3db86aabSstevel test_stop.condition = SYSC_CFGA_COND_FAILED;
939*3db86aabSstevel break;
940*3db86aabSstevel case CFGA_COND_UNKNOWN:
941*3db86aabSstevel test_stop.condition = SYSC_CFGA_COND_UNKNOWN;
942*3db86aabSstevel break;
943*3db86aabSstevel default:
944*3db86aabSstevel test_stop.condition = SYSC_CFGA_COND_UNKNOWN;
945*3db86aabSstevel assert(0);
946*3db86aabSstevel break;
947*3db86aabSstevel }
948*3db86aabSstevel
949*3db86aabSstevel mema_cmd_init(&cmd, &test_stop, outputstr, 0);
950*3db86aabSstevel dump_ioctl(AC_MEM_TEST_STOP, &test_stop);
951*3db86aabSstevel ret = ioctl(fd, AC_MEM_TEST_STOP, &cmd);
952*3db86aabSstevel ret_errno = errno;
953*3db86aabSstevel dump_ioctl_res(AC_MEM_TEST_STOP, &test_stop, ret, ret_errno);
954*3db86aabSstevel if (ret == -1) {
955*3db86aabSstevel mema_err(&cmd, ret_errno, errstring,
956*3db86aabSstevel CMD_MEM_TEST_STOP);
957*3db86aabSstevel return (CFGA_ERROR);
958*3db86aabSstevel }
959*3db86aabSstevel return (res);
960*3db86aabSstevel }
961*3db86aabSstevel
962*3db86aabSstevel #define DRVHANDLE(H) (((ac_mem_test_start_t *)(H)->drvhandle)->handle)
963*3db86aabSstevel
964*3db86aabSstevel int
mtest_write(mtest_handle_t handle,void * page_buf,u_longlong_t page_no,uint_t line_offset,uint_t line_count)965*3db86aabSstevel mtest_write(
966*3db86aabSstevel mtest_handle_t handle,
967*3db86aabSstevel void *page_buf,
968*3db86aabSstevel u_longlong_t page_no,
969*3db86aabSstevel uint_t line_offset,
970*3db86aabSstevel uint_t line_count)
971*3db86aabSstevel {
972*3db86aabSstevel ac_mem_test_write_t test_write;
973*3db86aabSstevel int fd, ret, ret_errno;
974*3db86aabSstevel ac_cfga_cmd_t cmd;
975*3db86aabSstevel char outputstr[AC_OUTPUT_LEN];
976*3db86aabSstevel
977*3db86aabSstevel (void) memset((void *)&test_write, 0, sizeof (test_write));
978*3db86aabSstevel fd = handle->fd;
979*3db86aabSstevel test_write.handle = DRVHANDLE(handle);
980*3db86aabSstevel test_write.page_buf = page_buf;
981*3db86aabSstevel test_write.address.page_num = page_no;
982*3db86aabSstevel test_write.address.line_offset = line_offset;
983*3db86aabSstevel if (line_count == 0)
984*3db86aabSstevel test_write.address.line_count = handle->lines_per_page;
985*3db86aabSstevel else
986*3db86aabSstevel test_write.address.line_count = line_count;
987*3db86aabSstevel
988*3db86aabSstevel mema_cmd_init(&cmd, &test_write, outputstr, 0);
989*3db86aabSstevel dump_ioctl(AC_MEM_TEST_WRITE, &test_write);
990*3db86aabSstevel ret = ioctl(fd, AC_MEM_TEST_WRITE, &cmd);
991*3db86aabSstevel ret_errno = errno;
992*3db86aabSstevel dump_ioctl_res(AC_MEM_TEST_WRITE, &test_write, ret, ret_errno);
993*3db86aabSstevel
994*3db86aabSstevel if (ret == -1)
995*3db86aabSstevel return (-1);
996*3db86aabSstevel return (0);
997*3db86aabSstevel }
998*3db86aabSstevel
999*3db86aabSstevel int
mtest_read(mtest_handle_t handle,void * page_buf,u_longlong_t page_no,uint_t line_offset,uint_t line_count,struct mtest_error * errp)1000*3db86aabSstevel mtest_read(
1001*3db86aabSstevel mtest_handle_t handle,
1002*3db86aabSstevel void *page_buf,
1003*3db86aabSstevel u_longlong_t page_no,
1004*3db86aabSstevel uint_t line_offset,
1005*3db86aabSstevel uint_t line_count,
1006*3db86aabSstevel struct mtest_error *errp)
1007*3db86aabSstevel {
1008*3db86aabSstevel ac_mem_test_read_t test_read;
1009*3db86aabSstevel sunfire_processor_error_regs_t errbuf;
1010*3db86aabSstevel int fd, ret, ret_errno;
1011*3db86aabSstevel ac_cfga_cmd_t cmd;
1012*3db86aabSstevel char outputstr[AC_OUTPUT_LEN];
1013*3db86aabSstevel
1014*3db86aabSstevel (void) memset((void *)&test_read, 0, sizeof (test_read));
1015*3db86aabSstevel (void) memset((void *)&errbuf, 0, sizeof (errbuf));
1016*3db86aabSstevel fd = handle->fd;
1017*3db86aabSstevel test_read.handle = DRVHANDLE(handle);
1018*3db86aabSstevel test_read.page_buf = page_buf;
1019*3db86aabSstevel test_read.address.page_num = page_no;
1020*3db86aabSstevel test_read.address.line_offset = line_offset;
1021*3db86aabSstevel test_read.error_buf = &errbuf;
1022*3db86aabSstevel if (line_count == 0)
1023*3db86aabSstevel test_read.address.line_count = handle->lines_per_page;
1024*3db86aabSstevel else
1025*3db86aabSstevel test_read.address.line_count = line_count;
1026*3db86aabSstevel
1027*3db86aabSstevel mema_cmd_init(&cmd, &test_read, outputstr, 0);
1028*3db86aabSstevel dump_ioctl(AC_MEM_TEST_READ, &test_read);
1029*3db86aabSstevel ret = ioctl(fd, AC_MEM_TEST_READ, &cmd);
1030*3db86aabSstevel ret_errno = errno;
1031*3db86aabSstevel dump_ioctl_res(AC_MEM_TEST_READ, &test_read, ret, ret_errno);
1032*3db86aabSstevel
1033*3db86aabSstevel if (ret == -1) {
1034*3db86aabSstevel if (ret_errno == EIO) {
1035*3db86aabSstevel /*
1036*3db86aabSstevel * Special case indicating CE or UE.
1037*3db86aabSstevel */
1038*3db86aabSstevel if (((errbuf.udbh_error_reg | errbuf.udbl_error_reg) &
1039*3db86aabSstevel P_DER_UE) != 0)
1040*3db86aabSstevel errp->error_type = MTEST_ERR_UE;
1041*3db86aabSstevel else
1042*3db86aabSstevel errp->error_type = MTEST_ERR_CE;
1043*3db86aabSstevel } else {
1044*3db86aabSstevel return (-1);
1045*3db86aabSstevel }
1046*3db86aabSstevel } else {
1047*3db86aabSstevel errp->error_type = MTEST_ERR_NONE;
1048*3db86aabSstevel }
1049*3db86aabSstevel return (0);
1050*3db86aabSstevel }
1051*3db86aabSstevel
1052*3db86aabSstevel static char *
subopt_help_str(char * opts[])1053*3db86aabSstevel subopt_help_str(char *opts[])
1054*3db86aabSstevel {
1055*3db86aabSstevel char *str;
1056*3db86aabSstevel const char *sep;
1057*3db86aabSstevel int len;
1058*3db86aabSstevel int i, n;
1059*3db86aabSstevel static const char help_sep[] = ", ";
1060*3db86aabSstevel static const char help_nil[] = "???";
1061*3db86aabSstevel
1062*3db86aabSstevel len = 0;
1063*3db86aabSstevel n = 0;
1064*3db86aabSstevel for (i = 0; opts[i] != NULL; i++) {
1065*3db86aabSstevel n++;
1066*3db86aabSstevel len += strlen(opts[i]);
1067*3db86aabSstevel }
1068*3db86aabSstevel if (n == 0)
1069*3db86aabSstevel return (strdup(help_nil));
1070*3db86aabSstevel len += (n - 1) * strlen(help_sep);
1071*3db86aabSstevel len++;
1072*3db86aabSstevel str = (char *)malloc(len);
1073*3db86aabSstevel if (str == NULL)
1074*3db86aabSstevel return (NULL);
1075*3db86aabSstevel *str = '\0';
1076*3db86aabSstevel sep = "";
1077*3db86aabSstevel for (i = 0; opts[i] != NULL; i++) {
1078*3db86aabSstevel (void) strcat(str, sep);
1079*3db86aabSstevel (void) strcat(str, opts[i]);
1080*3db86aabSstevel sep = help_sep;
1081*3db86aabSstevel }
1082*3db86aabSstevel return (str);
1083*3db86aabSstevel }
1084*3db86aabSstevel
1085*3db86aabSstevel /*ARGSUSED*/
1086*3db86aabSstevel cfga_err_t
cfga_test(const char * ap_id,const char * options,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)1087*3db86aabSstevel cfga_test(
1088*3db86aabSstevel const char *ap_id,
1089*3db86aabSstevel const char *options,
1090*3db86aabSstevel struct cfga_msg *msgp,
1091*3db86aabSstevel char **errstring,
1092*3db86aabSstevel cfga_flags_t flags)
1093*3db86aabSstevel {
1094*3db86aabSstevel mema_bank_t bk;
1095*3db86aabSstevel ac_stat_t stat;
1096*3db86aabSstevel int test_fun = -1;
1097*3db86aabSstevel int fd, ret;
1098*3db86aabSstevel int maxerr_idx;
1099*3db86aabSstevel long max_errors = -1;
1100*3db86aabSstevel char *ret_p;
1101*3db86aabSstevel
1102*3db86aabSstevel if (errstring != NULL)
1103*3db86aabSstevel *errstring = NULL;
1104*3db86aabSstevel
1105*3db86aabSstevel /*
1106*3db86aabSstevel * Decode test level and max error number.
1107*3db86aabSstevel */
1108*3db86aabSstevel if (options != NULL && *options != '\0') {
1109*3db86aabSstevel char **opts;
1110*3db86aabSstevel char *value;
1111*3db86aabSstevel char *cp, *free_cp;
1112*3db86aabSstevel int subopt;
1113*3db86aabSstevel
1114*3db86aabSstevel /* getsubopt() modifies the input string, so copy it. */
1115*3db86aabSstevel cp = strdup(options);
1116*3db86aabSstevel if (cp == NULL) {
1117*3db86aabSstevel return (CFGA_LIB_ERROR);
1118*3db86aabSstevel }
1119*3db86aabSstevel free_cp = cp;
1120*3db86aabSstevel opts = mtest_build_opts(&maxerr_idx);
1121*3db86aabSstevel if (opts == NULL) {
1122*3db86aabSstevel free((void *)free_cp);
1123*3db86aabSstevel return (CFGA_LIB_ERROR);
1124*3db86aabSstevel }
1125*3db86aabSstevel
1126*3db86aabSstevel while (*cp != '\0') {
1127*3db86aabSstevel subopt = getsubopt(&cp, opts, &value);
1128*3db86aabSstevel if (subopt == -1) {
1129*3db86aabSstevel char *hlp;
1130*3db86aabSstevel
1131*3db86aabSstevel hlp = subopt_help_str(opts);
1132*3db86aabSstevel if (hlp != NULL) {
1133*3db86aabSstevel __fmt_errstring(errstring,
1134*3db86aabSstevel strlen(value) + strlen(hlp),
1135*3db86aabSstevel dgettext(TEXT_DOMAIN, unk_test),
1136*3db86aabSstevel value, hlp);
1137*3db86aabSstevel free((void *)hlp);
1138*3db86aabSstevel } else {
1139*3db86aabSstevel __fmt_errstring(errstring, 20,
1140*3db86aabSstevel dgettext(TEXT_DOMAIN, calloc_fail),
1141*3db86aabSstevel strlen(options) + 1, 1);
1142*3db86aabSstevel }
1143*3db86aabSstevel /* Free after printing value. */
1144*3db86aabSstevel free((void *)free_cp);
1145*3db86aabSstevel return (CFGA_ERROR);
1146*3db86aabSstevel }
1147*3db86aabSstevel
1148*3db86aabSstevel if (test_fun != -1 && subopt != test_fun &&
1149*3db86aabSstevel subopt != maxerr_idx) {
1150*3db86aabSstevel __fmt_errstring(errstring,
1151*3db86aabSstevel strlen(opts[subopt]),
1152*3db86aabSstevel dgettext(TEXT_DOMAIN, dup_test),
1153*3db86aabSstevel opts[subopt]);
1154*3db86aabSstevel free((void *)free_cp);
1155*3db86aabSstevel return (CFGA_ERROR);
1156*3db86aabSstevel }
1157*3db86aabSstevel
1158*3db86aabSstevel if (subopt < maxerr_idx)
1159*3db86aabSstevel test_fun = subopt;
1160*3db86aabSstevel else {
1161*3db86aabSstevel
1162*3db86aabSstevel if (max_errors != -1 && subopt == maxerr_idx) {
1163*3db86aabSstevel __fmt_errstring(errstring,
1164*3db86aabSstevel strlen(opts[subopt]),
1165*3db86aabSstevel dgettext(TEXT_DOMAIN, dup_num),
1166*3db86aabSstevel opts[subopt]);
1167*3db86aabSstevel free((void *)free_cp);
1168*3db86aabSstevel return (CFGA_ERROR);
1169*3db86aabSstevel }
1170*3db86aabSstevel
1171*3db86aabSstevel if (value == NULL) {
1172*3db86aabSstevel __fmt_errstring(errstring,
1173*3db86aabSstevel 0,
1174*3db86aabSstevel dgettext(TEXT_DOMAIN, no_num),
1175*3db86aabSstevel "");
1176*3db86aabSstevel free((void *)free_cp);
1177*3db86aabSstevel return (CFGA_ERROR);
1178*3db86aabSstevel }
1179*3db86aabSstevel
1180*3db86aabSstevel max_errors = strtol(value, &ret_p, 10);
1181*3db86aabSstevel if ((ret_p == value) || (*ret_p != '\0') ||
1182*3db86aabSstevel (max_errors < 0)) {
1183*3db86aabSstevel __fmt_errstring(errstring,
1184*3db86aabSstevel strlen(value),
1185*3db86aabSstevel dgettext(TEXT_DOMAIN, no_num),
1186*3db86aabSstevel value);
1187*3db86aabSstevel free((void *)free_cp);
1188*3db86aabSstevel return (CFGA_ERROR);
1189*3db86aabSstevel }
1190*3db86aabSstevel }
1191*3db86aabSstevel }
1192*3db86aabSstevel free((void *)free_cp);
1193*3db86aabSstevel }
1194*3db86aabSstevel
1195*3db86aabSstevel if (test_fun == -1)
1196*3db86aabSstevel test_fun = MTEST_DEFAULT_TEST;
1197*3db86aabSstevel if (max_errors == -1)
1198*3db86aabSstevel max_errors = MAX_ERRORS;
1199*3db86aabSstevel
1200*3db86aabSstevel ret = ap_stat(ap_id, &fd, &bk, &stat, errstring);
1201*3db86aabSstevel if (ret != CFGA_OK)
1202*3db86aabSstevel return (ret);
1203*3db86aabSstevel
1204*3db86aabSstevel if (stat.rstate != SYSC_CFGA_RSTATE_CONNECTED ||
1205*3db86aabSstevel stat.ostate != SYSC_CFGA_OSTATE_UNCONFIGURED) {
1206*3db86aabSstevel __fmt_errstring(errstring, 0,
1207*3db86aabSstevel dgettext(TEXT_DOMAIN, trans_illegal));
1208*3db86aabSstevel (void) close(fd);
1209*3db86aabSstevel return (CFGA_ERROR);
1210*3db86aabSstevel }
1211*3db86aabSstevel
1212*3db86aabSstevel ret = mtest_run(fd, test_fun, &bk,
1213*3db86aabSstevel ((flags & CFGA_FLAG_VERBOSE) != 0) ? msgp : NULL, errstring,
1214*3db86aabSstevel (ulong_t)max_errors);
1215*3db86aabSstevel
1216*3db86aabSstevel (void) close(fd);
1217*3db86aabSstevel
1218*3db86aabSstevel return (ret);
1219*3db86aabSstevel }
1220*3db86aabSstevel
1221*3db86aabSstevel static cfga_stat_t
rstate_cvt(sysc_cfga_rstate_t rs)1222*3db86aabSstevel rstate_cvt(sysc_cfga_rstate_t rs)
1223*3db86aabSstevel {
1224*3db86aabSstevel cfga_stat_t cs;
1225*3db86aabSstevel
1226*3db86aabSstevel switch (rs) {
1227*3db86aabSstevel case SYSC_CFGA_RSTATE_EMPTY:
1228*3db86aabSstevel cs = CFGA_STAT_EMPTY;
1229*3db86aabSstevel break;
1230*3db86aabSstevel case SYSC_CFGA_RSTATE_DISCONNECTED:
1231*3db86aabSstevel cs = CFGA_STAT_DISCONNECTED;
1232*3db86aabSstevel break;
1233*3db86aabSstevel case SYSC_CFGA_RSTATE_CONNECTED:
1234*3db86aabSstevel cs = CFGA_STAT_CONNECTED;
1235*3db86aabSstevel break;
1236*3db86aabSstevel default:
1237*3db86aabSstevel cs = CFGA_STAT_NONE;
1238*3db86aabSstevel break;
1239*3db86aabSstevel }
1240*3db86aabSstevel
1241*3db86aabSstevel return (cs);
1242*3db86aabSstevel }
1243*3db86aabSstevel
1244*3db86aabSstevel static cfga_stat_t
ostate_cvt(sysc_cfga_ostate_t os)1245*3db86aabSstevel ostate_cvt(sysc_cfga_ostate_t os)
1246*3db86aabSstevel {
1247*3db86aabSstevel cfga_stat_t cs;
1248*3db86aabSstevel
1249*3db86aabSstevel switch (os) {
1250*3db86aabSstevel case SYSC_CFGA_OSTATE_UNCONFIGURED:
1251*3db86aabSstevel cs = CFGA_STAT_UNCONFIGURED;
1252*3db86aabSstevel break;
1253*3db86aabSstevel case SYSC_CFGA_OSTATE_CONFIGURED:
1254*3db86aabSstevel cs = CFGA_STAT_CONFIGURED;
1255*3db86aabSstevel break;
1256*3db86aabSstevel default:
1257*3db86aabSstevel cs = CFGA_STAT_NONE;
1258*3db86aabSstevel break;
1259*3db86aabSstevel }
1260*3db86aabSstevel
1261*3db86aabSstevel return (cs);
1262*3db86aabSstevel }
1263*3db86aabSstevel
1264*3db86aabSstevel static cfga_cond_t
cond_cvt(sysc_cfga_cond_t sc)1265*3db86aabSstevel cond_cvt(sysc_cfga_cond_t sc)
1266*3db86aabSstevel {
1267*3db86aabSstevel cfga_cond_t cc;
1268*3db86aabSstevel
1269*3db86aabSstevel switch (sc) {
1270*3db86aabSstevel case SYSC_CFGA_COND_OK:
1271*3db86aabSstevel cc = CFGA_COND_OK;
1272*3db86aabSstevel break;
1273*3db86aabSstevel case SYSC_CFGA_COND_FAILING:
1274*3db86aabSstevel cc = CFGA_COND_FAILING;
1275*3db86aabSstevel break;
1276*3db86aabSstevel case SYSC_CFGA_COND_FAILED:
1277*3db86aabSstevel cc = CFGA_COND_FAILED;
1278*3db86aabSstevel break;
1279*3db86aabSstevel case SYSC_CFGA_COND_UNUSABLE:
1280*3db86aabSstevel cc = CFGA_COND_UNUSABLE;
1281*3db86aabSstevel break;
1282*3db86aabSstevel case SYSC_CFGA_COND_UNKNOWN:
1283*3db86aabSstevel default:
1284*3db86aabSstevel cc = CFGA_COND_UNKNOWN;
1285*3db86aabSstevel break;
1286*3db86aabSstevel }
1287*3db86aabSstevel
1288*3db86aabSstevel return (cc);
1289*3db86aabSstevel }
1290*3db86aabSstevel
1291*3db86aabSstevel static void
info_set(ac_stat_t * asp,mema_bank_t * bkp,cfga_info_t info)1292*3db86aabSstevel info_set(ac_stat_t *asp, mema_bank_t *bkp, cfga_info_t info)
1293*3db86aabSstevel {
1294*3db86aabSstevel mema_disabled_t disab;
1295*3db86aabSstevel uint_t board;
1296*3db86aabSstevel uint_t n;
1297*3db86aabSstevel u_longlong_t decode;
1298*3db86aabSstevel uint_t intlv;
1299*3db86aabSstevel char *f;
1300*3db86aabSstevel char *end;
1301*3db86aabSstevel
1302*3db86aabSstevel end = &info[sizeof (cfga_info_t)];
1303*3db86aabSstevel *info = NULL;
1304*3db86aabSstevel
1305*3db86aabSstevel board = bkp->board;
1306*3db86aabSstevel
1307*3db86aabSstevel /* Print the board number in a way that matches the sysctrl AP. */
1308*3db86aabSstevel info += snprintf(info, end - info, "slot%d", board);
1309*3db86aabSstevel
1310*3db86aabSstevel if (asp->real_size == 0) {
1311*3db86aabSstevel info += snprintf(info, end - info, " empty");
1312*3db86aabSstevel return;
1313*3db86aabSstevel }
1314*3db86aabSstevel
1315*3db86aabSstevel if ((n = asp->real_size) >= 1024) {
1316*3db86aabSstevel n /= 1024;
1317*3db86aabSstevel f = "Gb";
1318*3db86aabSstevel } else
1319*3db86aabSstevel f = "Mb";
1320*3db86aabSstevel info += snprintf(info, end - info, " %d%s", n, f);
1321*3db86aabSstevel
1322*3db86aabSstevel if (asp->rstate == SYSC_CFGA_RSTATE_CONNECTED &&
1323*3db86aabSstevel asp->ostate == SYSC_CFGA_OSTATE_CONFIGURED &&
1324*3db86aabSstevel asp->use_size != asp->real_size) {
1325*3db86aabSstevel if ((n = asp->use_size) >= 1024) {
1326*3db86aabSstevel n /= 1024;
1327*3db86aabSstevel f = "Gb";
1328*3db86aabSstevel } else
1329*3db86aabSstevel f = "Mb";
1330*3db86aabSstevel info += snprintf(info, end - info, " (%d%s used)", n, f);
1331*3db86aabSstevel }
1332*3db86aabSstevel
1333*3db86aabSstevel if (bkp->bank == 0)
1334*3db86aabSstevel decode = asp->ac_decode0;
1335*3db86aabSstevel else
1336*3db86aabSstevel decode = asp->ac_decode1;
1337*3db86aabSstevel
1338*3db86aabSstevel info += snprintf(info, end - info, " base 0x%llx",
1339*3db86aabSstevel GRP_REALBASE(decode));
1340*3db86aabSstevel
1341*3db86aabSstevel if (bkp->bank == 0)
1342*3db86aabSstevel intlv = INTLV0(asp->ac_memctl);
1343*3db86aabSstevel else
1344*3db86aabSstevel intlv = INTLV1(asp->ac_memctl);
1345*3db86aabSstevel
1346*3db86aabSstevel if (intlv != 1)
1347*3db86aabSstevel info += snprintf(info, end - info, " interleaved %u-way",
1348*3db86aabSstevel intlv);
1349*3db86aabSstevel
1350*3db86aabSstevel if (prom_read_disabled_list(&disab, board)) {
1351*3db86aabSstevel if (disab != 0) {
1352*3db86aabSstevel info += snprintf(info, end - info, " disabled at boot");
1353*3db86aabSstevel }
1354*3db86aabSstevel
1355*3db86aabSstevel }
1356*3db86aabSstevel
1357*3db86aabSstevel if (asp->rstate == SYSC_CFGA_RSTATE_CONNECTED &&
1358*3db86aabSstevel asp->ostate == SYSC_CFGA_OSTATE_CONFIGURED &&
1359*3db86aabSstevel asp->nonrelocatable)
1360*3db86aabSstevel info += snprintf(info, end - info, " permanent");
1361*3db86aabSstevel }
1362*3db86aabSstevel
1363*3db86aabSstevel static void
mema_cvt(ac_stat_t * ac,mema_bank_t * bkp,cfga_stat_data_t * cs)1364*3db86aabSstevel mema_cvt(ac_stat_t *ac, mema_bank_t *bkp, cfga_stat_data_t *cs)
1365*3db86aabSstevel {
1366*3db86aabSstevel (void) strcpy(cs->ap_type, "memory");
1367*3db86aabSstevel cs->ap_r_state = rstate_cvt(ac->rstate);
1368*3db86aabSstevel cs->ap_o_state = ostate_cvt(ac->ostate);
1369*3db86aabSstevel cs->ap_cond = cond_cvt(ac->condition);
1370*3db86aabSstevel cs->ap_busy = (cfga_busy_t)ac->busy;
1371*3db86aabSstevel cs->ap_status_time = ac->status_time;
1372*3db86aabSstevel info_set(ac, bkp, cs->ap_info);
1373*3db86aabSstevel cs->ap_log_id[0] = NULL;
1374*3db86aabSstevel cs->ap_phys_id[0] = NULL;
1375*3db86aabSstevel }
1376*3db86aabSstevel
1377*3db86aabSstevel /*ARGSUSED*/
1378*3db86aabSstevel cfga_err_t
cfga_stat(const char * ap_id,struct cfga_stat_data * cs,const char * options,char ** errstring)1379*3db86aabSstevel cfga_stat(
1380*3db86aabSstevel const char *ap_id,
1381*3db86aabSstevel struct cfga_stat_data *cs,
1382*3db86aabSstevel const char *options,
1383*3db86aabSstevel char **errstring)
1384*3db86aabSstevel {
1385*3db86aabSstevel int ret;
1386*3db86aabSstevel mema_bank_t bk;
1387*3db86aabSstevel ac_stat_t stat;
1388*3db86aabSstevel option_set_t do_option;
1389*3db86aabSstevel
1390*3db86aabSstevel if (errstring != NULL)
1391*3db86aabSstevel *errstring = NULL;
1392*3db86aabSstevel
1393*3db86aabSstevel ret = 0;
1394*3db86aabSstevel do_option = process_options(options, stat_opts, &ret, errstring);
1395*3db86aabSstevel if (ret != 0)
1396*3db86aabSstevel return (ret);
1397*3db86aabSstevel
1398*3db86aabSstevel ret = ap_stat(ap_id, NULL, &bk, &stat, errstring);
1399*3db86aabSstevel if (ret != CFGA_OK)
1400*3db86aabSstevel return (ret);
1401*3db86aabSstevel
1402*3db86aabSstevel mema_cvt(&stat, &bk, cs);
1403*3db86aabSstevel
1404*3db86aabSstevel ret = prom_do_options(do_option, bk.board, &stat, errstring);
1405*3db86aabSstevel
1406*3db86aabSstevel return (ret);
1407*3db86aabSstevel }
1408*3db86aabSstevel
1409*3db86aabSstevel /*ARGSUSED*/
1410*3db86aabSstevel cfga_err_t
cfga_list(const char * ap_id,cfga_stat_data_t ** ap_list,int * nlist,const char * options,char ** errstring)1411*3db86aabSstevel cfga_list(
1412*3db86aabSstevel const char *ap_id,
1413*3db86aabSstevel cfga_stat_data_t **ap_list,
1414*3db86aabSstevel int *nlist,
1415*3db86aabSstevel const char *options,
1416*3db86aabSstevel char **errstring)
1417*3db86aabSstevel {
1418*3db86aabSstevel if (errstring != NULL)
1419*3db86aabSstevel *errstring = NULL;
1420*3db86aabSstevel
1421*3db86aabSstevel return (CFGA_NOTSUPP);
1422*3db86aabSstevel }
1423*3db86aabSstevel
1424*3db86aabSstevel /*
1425*3db86aabSstevel * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
1426*3db86aabSstevel */
1427*3db86aabSstevel
1428*3db86aabSstevel /*ARGSUSED*/
1429*3db86aabSstevel cfga_err_t
cfga_help(struct cfga_msg * msgp,const char * options,cfga_flags_t flags)1430*3db86aabSstevel cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
1431*3db86aabSstevel {
1432*3db86aabSstevel
1433*3db86aabSstevel
1434*3db86aabSstevel (*msgp->message_routine)(msgp->appdata_ptr, mema_help);
1435*3db86aabSstevel (*msgp->message_routine)(msgp->appdata_ptr, disable_opts);
1436*3db86aabSstevel (*msgp->message_routine)(msgp->appdata_ptr, enable_opts);
1437*3db86aabSstevel (*msgp->message_routine)(msgp->appdata_ptr, timeout_opts);
1438*3db86aabSstevel (*msgp->message_routine)(msgp->appdata_ptr, test_opts);
1439*3db86aabSstevel (*msgp->message_routine)(msgp->appdata_ptr, private_funcs);
1440*3db86aabSstevel
1441*3db86aabSstevel return (CFGA_OK);
1442*3db86aabSstevel }
1443*3db86aabSstevel
1444*3db86aabSstevel #if 0
1445*3db86aabSstevel static ac_mem_version_t
1446*3db86aabSstevel get_version(int fd)
1447*3db86aabSstevel {
1448*3db86aabSstevel ac_mem_version_t ver;
1449*3db86aabSstevel int ret, ret_errno;
1450*3db86aabSstevel
1451*3db86aabSstevel ver = 0;
1452*3db86aabSstevel dump_ioctl(AC_MEM_ADMIN_VER, &ver);
1453*3db86aabSstevel ret = ioctl(fd, AC_MEM_ADMIN_VER, &ver);
1454*3db86aabSstevel ret_errno = errno;
1455*3db86aabSstevel dump_ioctl_res(AC_MEM_ADMIN_VER, &ver, ret, ret_errno);
1456*3db86aabSstevel return (ver);
1457*3db86aabSstevel }
1458*3db86aabSstevel #endif
1459*3db86aabSstevel
1460*3db86aabSstevel static char *
opt_help_str(struct opt_control * opts)1461*3db86aabSstevel opt_help_str(struct opt_control *opts)
1462*3db86aabSstevel {
1463*3db86aabSstevel char *str;
1464*3db86aabSstevel const char *sep;
1465*3db86aabSstevel int len;
1466*3db86aabSstevel int i, n;
1467*3db86aabSstevel static const char help_sep[] = ", ";
1468*3db86aabSstevel static const char help_nil[] = "???";
1469*3db86aabSstevel
1470*3db86aabSstevel len = 0;
1471*3db86aabSstevel n = 0;
1472*3db86aabSstevel for (i = 0; opts[i].subopt != -1; i++) {
1473*3db86aabSstevel n++;
1474*3db86aabSstevel len += strlen(mema_opts[opts[i].subopt]);
1475*3db86aabSstevel }
1476*3db86aabSstevel if (n == 0)
1477*3db86aabSstevel return (strdup(help_nil));
1478*3db86aabSstevel len += (n - 1) * strlen(help_sep);
1479*3db86aabSstevel len++;
1480*3db86aabSstevel str = (char *)malloc(len);
1481*3db86aabSstevel if (str == NULL)
1482*3db86aabSstevel return (NULL);
1483*3db86aabSstevel *str = '\0';
1484*3db86aabSstevel sep = "";
1485*3db86aabSstevel for (i = 0; opts[i].subopt != -1; i++) {
1486*3db86aabSstevel (void) strcat(str, sep);
1487*3db86aabSstevel (void) strcat(str, mema_opts[opts[i].subopt]);
1488*3db86aabSstevel sep = help_sep;
1489*3db86aabSstevel }
1490*3db86aabSstevel return (str);
1491*3db86aabSstevel }
1492*3db86aabSstevel
1493*3db86aabSstevel static option_set_t
process_options(const char * options,struct opt_control * opts,int * retp,char ** errstring)1494*3db86aabSstevel process_options(
1495*3db86aabSstevel const char *options,
1496*3db86aabSstevel struct opt_control *opts,
1497*3db86aabSstevel int *retp,
1498*3db86aabSstevel char **errstring)
1499*3db86aabSstevel {
1500*3db86aabSstevel option_set_t opt_set;
1501*3db86aabSstevel char *optcopy, *optcopy_alloc;
1502*3db86aabSstevel char *value;
1503*3db86aabSstevel int subopt;
1504*3db86aabSstevel int subopt_err;
1505*3db86aabSstevel int i;
1506*3db86aabSstevel int group;
1507*3db86aabSstevel int need_value;
1508*3db86aabSstevel
1509*3db86aabSstevel OPTSET_INIT(opt_set);
1510*3db86aabSstevel
1511*3db86aabSstevel if (options == NULL || *options == '\0') {
1512*3db86aabSstevel return (opt_set);
1513*3db86aabSstevel }
1514*3db86aabSstevel
1515*3db86aabSstevel optcopy = optcopy_alloc = strdup(options);
1516*3db86aabSstevel if (optcopy_alloc == NULL) {
1517*3db86aabSstevel __fmt_errstring(errstring, 20,
1518*3db86aabSstevel dgettext(TEXT_DOMAIN, calloc_fail), strlen(options) + 1, 1);
1519*3db86aabSstevel *retp = CFGA_LIB_ERROR;
1520*3db86aabSstevel return (opt_set);
1521*3db86aabSstevel }
1522*3db86aabSstevel
1523*3db86aabSstevel subopt_err = 0;
1524*3db86aabSstevel while (*optcopy != '\0' && subopt_err == 0) {
1525*3db86aabSstevel subopt = getsubopt(&optcopy, mema_opts, &value);
1526*3db86aabSstevel if (subopt == -1) {
1527*3db86aabSstevel char *hlp;
1528*3db86aabSstevel
1529*3db86aabSstevel hlp = opt_help_str(opts);
1530*3db86aabSstevel __fmt_errstring(errstring, strlen(value) + strlen(hlp),
1531*3db86aabSstevel dgettext(TEXT_DOMAIN, unk_subopt), value, hlp);
1532*3db86aabSstevel free((void *)hlp);
1533*3db86aabSstevel subopt_err = 1;
1534*3db86aabSstevel break;
1535*3db86aabSstevel }
1536*3db86aabSstevel for (i = 0; opts[i].subopt != -1; i++) {
1537*3db86aabSstevel if (opts[i].subopt == subopt) {
1538*3db86aabSstevel group = opts[i].group;
1539*3db86aabSstevel break;
1540*3db86aabSstevel }
1541*3db86aabSstevel }
1542*3db86aabSstevel if (opts[i].subopt == -1) {
1543*3db86aabSstevel char *hlp;
1544*3db86aabSstevel
1545*3db86aabSstevel hlp = opt_help_str(opts);
1546*3db86aabSstevel __fmt_errstring(errstring,
1547*3db86aabSstevel MAX_OPT_LENGTH + strlen(hlp),
1548*3db86aabSstevel dgettext(TEXT_DOMAIN, not_valid),
1549*3db86aabSstevel mema_opts[subopt], hlp);
1550*3db86aabSstevel free((void *)hlp);
1551*3db86aabSstevel subopt_err = 1;
1552*3db86aabSstevel break;
1553*3db86aabSstevel }
1554*3db86aabSstevel need_value = OPT_NEEDS_VALUE(subopt);
1555*3db86aabSstevel if (!need_value && value != NULL) {
1556*3db86aabSstevel __fmt_errstring(errstring, MAX_OPT_LENGTH,
1557*3db86aabSstevel dgettext(TEXT_DOMAIN, no_value),
1558*3db86aabSstevel mema_opts[subopt]);
1559*3db86aabSstevel subopt_err = 1;
1560*3db86aabSstevel break;
1561*3db86aabSstevel }
1562*3db86aabSstevel if (need_value && value == NULL) {
1563*3db86aabSstevel __fmt_errstring(errstring, MAX_OPT_LENGTH,
1564*3db86aabSstevel dgettext(TEXT_DOMAIN, missing_value),
1565*3db86aabSstevel mema_opts[subopt]);
1566*3db86aabSstevel subopt_err = 1;
1567*3db86aabSstevel break;
1568*3db86aabSstevel }
1569*3db86aabSstevel if (OPTSET_TEST(opt_set, subopt)) {
1570*3db86aabSstevel /* Ignore repeated options. */
1571*3db86aabSstevel continue;
1572*3db86aabSstevel }
1573*3db86aabSstevel if (group != 0 && !OPTSET_IS_EMPTY(opt_set)) {
1574*3db86aabSstevel for (i = 0; opts[i].subopt != -1; i++) {
1575*3db86aabSstevel if (i == subopt)
1576*3db86aabSstevel continue;
1577*3db86aabSstevel if (opts[i].group == group &&
1578*3db86aabSstevel OPTSET_TEST(opt_set, opts[i].subopt))
1579*3db86aabSstevel break;
1580*3db86aabSstevel }
1581*3db86aabSstevel if (opts[i].subopt != -1) {
1582*3db86aabSstevel __fmt_errstring(errstring, MAX_OPT_LENGTH * 2,
1583*3db86aabSstevel dgettext(TEXT_DOMAIN, conflict_opt),
1584*3db86aabSstevel mema_opts[subopt],
1585*3db86aabSstevel mema_opts[opts[i].subopt]);
1586*3db86aabSstevel subopt_err = 1;
1587*3db86aabSstevel break;
1588*3db86aabSstevel }
1589*3db86aabSstevel }
1590*3db86aabSstevel OPTSET_SET_VAL(opt_set, subopt, value);
1591*3db86aabSstevel }
1592*3db86aabSstevel free((void *)optcopy_alloc);
1593*3db86aabSstevel if (subopt_err) {
1594*3db86aabSstevel *retp = CFGA_ERROR;
1595*3db86aabSstevel }
1596*3db86aabSstevel
1597*3db86aabSstevel return (opt_set);
1598*3db86aabSstevel }
1599*3db86aabSstevel
1600*3db86aabSstevel #ifdef DEV_DEBUG
1601*3db86aabSstevel
1602*3db86aabSstevel static int
debugging(void)1603*3db86aabSstevel debugging(void)
1604*3db86aabSstevel {
1605*3db86aabSstevel char *ep;
1606*3db86aabSstevel static int inited;
1607*3db86aabSstevel
1608*3db86aabSstevel if (inited)
1609*3db86aabSstevel return (debug_fp != NULL);
1610*3db86aabSstevel inited = 1;
1611*3db86aabSstevel
1612*3db86aabSstevel if ((ep = getenv("MEMADM_DEBUG")) == NULL) {
1613*3db86aabSstevel return (0);
1614*3db86aabSstevel }
1615*3db86aabSstevel if (*ep == '\0')
1616*3db86aabSstevel debug_fp = stderr;
1617*3db86aabSstevel else {
1618*3db86aabSstevel if ((debug_fp = fopen(ep, "a")) == NULL)
1619*3db86aabSstevel return (0);
1620*3db86aabSstevel }
1621*3db86aabSstevel (void) fprintf(debug_fp, "\nDebug started, pid=%d\n", (int)getpid());
1622*3db86aabSstevel return (1);
1623*3db86aabSstevel }
1624*3db86aabSstevel
1625*3db86aabSstevel static void
dump_ioctl(int cmd,void * arg)1626*3db86aabSstevel dump_ioctl(
1627*3db86aabSstevel int cmd,
1628*3db86aabSstevel void *arg)
1629*3db86aabSstevel {
1630*3db86aabSstevel if (!debugging())
1631*3db86aabSstevel return;
1632*3db86aabSstevel
1633*3db86aabSstevel switch (cmd) {
1634*3db86aabSstevel case AC_MEM_CONFIGURE:
1635*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_CONFIGURE\n");
1636*3db86aabSstevel break;
1637*3db86aabSstevel
1638*3db86aabSstevel case AC_MEM_UNCONFIGURE:
1639*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_UNCONFIGURE\n");
1640*3db86aabSstevel break;
1641*3db86aabSstevel
1642*3db86aabSstevel case AC_MEM_TEST_START:
1643*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_START\n");
1644*3db86aabSstevel break;
1645*3db86aabSstevel
1646*3db86aabSstevel case AC_MEM_TEST_STOP: {
1647*3db86aabSstevel ac_mem_test_stop_t *tstop;
1648*3db86aabSstevel
1649*3db86aabSstevel tstop = (ac_mem_test_stop_t *)arg;
1650*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_STOP handle=%#x "
1651*3db86aabSstevel "condition=%d\n", tstop->handle, tstop->condition);
1652*3db86aabSstevel }
1653*3db86aabSstevel break;
1654*3db86aabSstevel case AC_MEM_TEST_READ: {
1655*3db86aabSstevel ac_mem_test_read_t *tread;
1656*3db86aabSstevel
1657*3db86aabSstevel tread = (ac_mem_test_read_t *)arg;
1658*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_READ handle=%#x "
1659*3db86aabSstevel "buf=%#p page=%#llx off=%#x count=%#x\n",
1660*3db86aabSstevel tread->handle, tread->page_buf,
1661*3db86aabSstevel tread->address.page_num,
1662*3db86aabSstevel tread->address.line_offset, tread->address.line_count);
1663*3db86aabSstevel }
1664*3db86aabSstevel break;
1665*3db86aabSstevel case AC_MEM_TEST_WRITE: {
1666*3db86aabSstevel ac_mem_test_write_t *twrite;
1667*3db86aabSstevel
1668*3db86aabSstevel twrite = (ac_mem_test_write_t *)arg;
1669*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_WRITE handle=%#x "
1670*3db86aabSstevel "buf=%#p page=%#llx off=%#x count=%#x\n",
1671*3db86aabSstevel twrite->handle, twrite->page_buf,
1672*3db86aabSstevel twrite->address.page_num,
1673*3db86aabSstevel twrite->address.line_offset, twrite->address.line_count);
1674*3db86aabSstevel }
1675*3db86aabSstevel break;
1676*3db86aabSstevel case AC_MEM_ADMIN_VER:
1677*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_ADMIN_VER:\n");
1678*3db86aabSstevel break;
1679*3db86aabSstevel case AC_MEM_STAT:
1680*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_STAT\n");
1681*3db86aabSstevel break;
1682*3db86aabSstevel case AC_MEM_EXERCISE: {
1683*3db86aabSstevel ac_cfga_cmd_t *cmdp;
1684*3db86aabSstevel
1685*3db86aabSstevel cmdp = arg;
1686*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_EXERCISE arg=%d\n",
1687*3db86aabSstevel cmdp->arg);
1688*3db86aabSstevel break;
1689*3db86aabSstevel }
1690*3db86aabSstevel default:
1691*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL: unknown (%#x)\n", cmd);
1692*3db86aabSstevel break;
1693*3db86aabSstevel }
1694*3db86aabSstevel (void) fflush(debug_fp);
1695*3db86aabSstevel }
1696*3db86aabSstevel
1697*3db86aabSstevel static void
dump_ioctl_res(int cmd,void * arg,int ret,int ret_errno)1698*3db86aabSstevel dump_ioctl_res(
1699*3db86aabSstevel int cmd,
1700*3db86aabSstevel void *arg,
1701*3db86aabSstevel int ret,
1702*3db86aabSstevel int ret_errno)
1703*3db86aabSstevel {
1704*3db86aabSstevel if (!debugging())
1705*3db86aabSstevel return;
1706*3db86aabSstevel
1707*3db86aabSstevel if (ret == -1) {
1708*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL failed, \"%s\" (errno=%d)\n",
1709*3db86aabSstevel strerror(ret_errno), ret_errno);
1710*3db86aabSstevel (void) fflush(debug_fp);
1711*3db86aabSstevel return;
1712*3db86aabSstevel } else {
1713*3db86aabSstevel (void) fprintf(debug_fp, "IOCTL succeeded, ret=%d\n", ret);
1714*3db86aabSstevel }
1715*3db86aabSstevel
1716*3db86aabSstevel switch (cmd) {
1717*3db86aabSstevel case AC_MEM_CONFIGURE:
1718*3db86aabSstevel case AC_MEM_UNCONFIGURE:
1719*3db86aabSstevel break;
1720*3db86aabSstevel case AC_MEM_TEST_START: {
1721*3db86aabSstevel ac_mem_test_start_t *tstart;
1722*3db86aabSstevel
1723*3db86aabSstevel tstart = (ac_mem_test_start_t *)arg;
1724*3db86aabSstevel (void) fprintf(debug_fp, " handle=%#x tester_pid=%d "
1725*3db86aabSstevel "prev_condition=%d bank_size=%#llx "
1726*3db86aabSstevel "page_size=%#x line_size=%#x afar_base=%#llx\n",
1727*3db86aabSstevel tstart->handle, (int)tstart->tester_pid,
1728*3db86aabSstevel tstart->prev_condition,
1729*3db86aabSstevel tstart->bank_size, tstart->page_size,
1730*3db86aabSstevel tstart->line_size, tstart->afar_base);
1731*3db86aabSstevel }
1732*3db86aabSstevel break;
1733*3db86aabSstevel case AC_MEM_TEST_STOP:
1734*3db86aabSstevel break;
1735*3db86aabSstevel case AC_MEM_TEST_READ: {
1736*3db86aabSstevel ac_mem_test_read_t *tread;
1737*3db86aabSstevel sunfire_processor_error_regs_t *err;
1738*3db86aabSstevel
1739*3db86aabSstevel tread = (ac_mem_test_read_t *)arg;
1740*3db86aabSstevel err = tread->error_buf;
1741*3db86aabSstevel if (ret_errno == EIO) {
1742*3db86aabSstevel (void) fprintf(debug_fp, "module_id=%#llx afsr=%#llx "
1743*3db86aabSstevel "afar=%#llx udbh_error_reg=%#llx "
1744*3db86aabSstevel "udbl_error_reg=%#llx\n",
1745*3db86aabSstevel (longlong_t)err->module_id, (longlong_t)err->afsr,
1746*3db86aabSstevel (longlong_t)err->afar,
1747*3db86aabSstevel (longlong_t)err->udbh_error_reg,
1748*3db86aabSstevel (longlong_t)err->udbl_error_reg);
1749*3db86aabSstevel } else {
1750*3db86aabSstevel (void) fprintf(debug_fp, "\n");
1751*3db86aabSstevel }
1752*3db86aabSstevel }
1753*3db86aabSstevel break;
1754*3db86aabSstevel case AC_MEM_TEST_WRITE:
1755*3db86aabSstevel break;
1756*3db86aabSstevel case AC_MEM_ADMIN_VER: {
1757*3db86aabSstevel ac_mem_version_t *ver;
1758*3db86aabSstevel
1759*3db86aabSstevel ver = (ac_mem_version_t *)arg;
1760*3db86aabSstevel (void) fprintf(debug_fp, " version %d\n", *ver);
1761*3db86aabSstevel }
1762*3db86aabSstevel break;
1763*3db86aabSstevel case AC_MEM_STAT: {
1764*3db86aabSstevel ac_stat_t *tstat;
1765*3db86aabSstevel
1766*3db86aabSstevel tstat = (ac_stat_t *)arg;
1767*3db86aabSstevel (void) fprintf(debug_fp, " rstate=%u ostate=%u "
1768*3db86aabSstevel "condition=%u status_time=%#lx board=%u\n",
1769*3db86aabSstevel (uint_t)tstat->rstate, (uint_t)tstat->ostate,
1770*3db86aabSstevel (uint_t)tstat->condition, (ulong_t)tstat->status_time,
1771*3db86aabSstevel tstat->board);
1772*3db86aabSstevel (void) fprintf(debug_fp, " real_size=%u use_size=%u "
1773*3db86aabSstevel "busy=%u\n",
1774*3db86aabSstevel tstat->real_size, tstat->use_size, tstat->busy);
1775*3db86aabSstevel (void) fprintf(debug_fp, " page_size=%#x "
1776*3db86aabSstevel "phys_pages=%#llx managed=%#llx nonrelocatable=%#llx\n",
1777*3db86aabSstevel tstat->page_size, (longlong_t)tstat->phys_pages,
1778*3db86aabSstevel (longlong_t)tstat->managed,
1779*3db86aabSstevel (longlong_t)tstat->nonrelocatable);
1780*3db86aabSstevel (void) fprintf(debug_fp, " memctl=%#llx "
1781*3db86aabSstevel "decode0=%#llx decode1=%#llx\n",
1782*3db86aabSstevel (longlong_t)tstat->ac_memctl, (longlong_t)tstat->ac_decode0,
1783*3db86aabSstevel (longlong_t)tstat->ac_decode1);
1784*3db86aabSstevel }
1785*3db86aabSstevel break;
1786*3db86aabSstevel case AC_MEM_EXERCISE: {
1787*3db86aabSstevel ac_cfga_cmd_t *cmdp;
1788*3db86aabSstevel
1789*3db86aabSstevel cmdp = arg;
1790*3db86aabSstevel switch (cmdp->arg) {
1791*3db86aabSstevel case AC_MEMX_RELOCATE_ALL: {
1792*3db86aabSstevel struct ac_memx_relocate_stats *stp;
1793*3db86aabSstevel
1794*3db86aabSstevel if ((stp = cmdp->private) != NULL) {
1795*3db86aabSstevel (void) fprintf(debug_fp, " base=%u npgs=%u"
1796*3db86aabSstevel " nopaget=%u nolock=%u isfree=%u reloc=%u"
1797*3db86aabSstevel " noreloc=%u\n",
1798*3db86aabSstevel stp->base, stp->npgs, stp->nopaget,
1799*3db86aabSstevel stp->nolock, stp->isfree, stp->reloc,
1800*3db86aabSstevel stp->noreloc);
1801*3db86aabSstevel }
1802*3db86aabSstevel break;
1803*3db86aabSstevel }
1804*3db86aabSstevel default:
1805*3db86aabSstevel break;
1806*3db86aabSstevel }
1807*3db86aabSstevel break;
1808*3db86aabSstevel }
1809*3db86aabSstevel default:
1810*3db86aabSstevel break;
1811*3db86aabSstevel }
1812*3db86aabSstevel (void) fflush(debug_fp);
1813*3db86aabSstevel }
1814*3db86aabSstevel #endif /* DEV_DEBUG */
1815