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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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