1*1991Sheppo /* 2*1991Sheppo * CDDL HEADER START 3*1991Sheppo * 4*1991Sheppo * The contents of this file are subject to the terms of the 5*1991Sheppo * Common Development and Distribution License (the "License"). 6*1991Sheppo * You may not use this file except in compliance with the License. 7*1991Sheppo * 8*1991Sheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*1991Sheppo * or http://www.opensolaris.org/os/licensing. 10*1991Sheppo * See the License for the specific language governing permissions 11*1991Sheppo * and limitations under the License. 12*1991Sheppo * 13*1991Sheppo * When distributing Covered Code, include this CDDL HEADER in each 14*1991Sheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*1991Sheppo * If applicable, add the following below this CDDL HEADER, with the 16*1991Sheppo * fields enclosed by brackets "[]" replaced with your own identifying 17*1991Sheppo * information: Portions Copyright [yyyy] [name of copyright owner] 18*1991Sheppo * 19*1991Sheppo * CDDL HEADER END 20*1991Sheppo */ 21*1991Sheppo 22*1991Sheppo /* 23*1991Sheppo * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*1991Sheppo * Use is subject to license terms. 25*1991Sheppo */ 26*1991Sheppo 27*1991Sheppo #pragma ident "%Z%%M% %I% %E% SMI" 28*1991Sheppo 29*1991Sheppo /* 30*1991Sheppo * sun4v DR Utility functions 31*1991Sheppo */ 32*1991Sheppo 33*1991Sheppo #include <sys/types.h> 34*1991Sheppo #include <sys/cmn_err.h> 35*1991Sheppo #include <sys/sunddi.h> 36*1991Sheppo #include <sys/note.h> 37*1991Sheppo #include <sys/sysevent.h> 38*1991Sheppo #include <sys/sysevent/dr.h> 39*1991Sheppo #include <sys/sysevent/eventdefs.h> 40*1991Sheppo #include <sys/ldoms.h> 41*1991Sheppo 42*1991Sheppo #include <sys/dr_util.h> 43*1991Sheppo 44*1991Sheppo boolean_t 45*1991Sheppo dr_is_disabled(dr_type_t type) 46*1991Sheppo { 47*1991Sheppo /* 48*1991Sheppo * The type argument is currently unused. However, it 49*1991Sheppo * keeps the interface flexible enough to allows for 50*1991Sheppo * only disabling certain types of DR. 51*1991Sheppo */ 52*1991Sheppo _NOTE(ARGUNUSED(type)) 53*1991Sheppo 54*1991Sheppo /* 55*1991Sheppo * DR requires that the kernel is using its own CIF 56*1991Sheppo * handler. If that is not the case, either because 57*1991Sheppo * domaining has been explicitly disabled, or because 58*1991Sheppo * the firmware does not support it, the system must 59*1991Sheppo * remain static and DR must be disabled. 60*1991Sheppo */ 61*1991Sheppo if (!domaining_enabled) { 62*1991Sheppo cmn_err(CE_NOTE, "!Kernel CIF handler is not enabled, DR " 63*1991Sheppo "is not available\n"); 64*1991Sheppo return (B_TRUE); 65*1991Sheppo } 66*1991Sheppo 67*1991Sheppo return (B_FALSE); 68*1991Sheppo } 69*1991Sheppo 70*1991Sheppo /* 71*1991Sheppo * Generate a DR sysevent based on the type of resource and 72*1991Sheppo * sysevent hint specified. The hint indicates whether the 73*1991Sheppo * resource was added or removed. 74*1991Sheppo */ 75*1991Sheppo void 76*1991Sheppo dr_generate_event(dr_type_t type, int se_hint) 77*1991Sheppo { 78*1991Sheppo int rv; 79*1991Sheppo sysevent_id_t eid; 80*1991Sheppo sysevent_t *ev = NULL; 81*1991Sheppo sysevent_attr_list_t *evnt_attr_list = NULL; 82*1991Sheppo sysevent_value_t evnt_val; 83*1991Sheppo static char pubname[] = SUNW_KERN_PUB"dr"; 84*1991Sheppo 85*1991Sheppo DR_DBG_ALL("generate_event: type=%s, hint=%s\n", DR_TYPE2STR(type), 86*1991Sheppo SE_HINT2STR(se_hint)); 87*1991Sheppo 88*1991Sheppo /* 89*1991Sheppo * Add the attachment point attribute 90*1991Sheppo */ 91*1991Sheppo ev = sysevent_alloc(EC_DR, ESC_DR_AP_STATE_CHANGE, pubname, KM_SLEEP); 92*1991Sheppo evnt_val.value_type = SE_DATA_TYPE_STRING; 93*1991Sheppo evnt_val.value.sv_string = DR_TYPE2STR(type); 94*1991Sheppo 95*1991Sheppo rv = sysevent_add_attr(&evnt_attr_list, DR_AP_ID, &evnt_val, KM_SLEEP); 96*1991Sheppo if (rv != 0) { 97*1991Sheppo DR_DBG_ALL("generate_event: failed to add attr '%s' for " 98*1991Sheppo "'%s' event\n", DR_AP_ID, EC_DR); 99*1991Sheppo goto done; 100*1991Sheppo } 101*1991Sheppo 102*1991Sheppo /* 103*1991Sheppo * Add the DR hint attribute 104*1991Sheppo */ 105*1991Sheppo evnt_val.value_type = SE_DATA_TYPE_STRING; 106*1991Sheppo evnt_val.value.sv_string = SE_HINT2STR(se_hint); 107*1991Sheppo 108*1991Sheppo rv = sysevent_add_attr(&evnt_attr_list, DR_HINT, &evnt_val, KM_SLEEP); 109*1991Sheppo if (rv != 0) { 110*1991Sheppo DR_DBG_ALL("generate_event: failed to add attr '%s' for " 111*1991Sheppo "'%s' event\n", DR_HINT, EC_DR); 112*1991Sheppo sysevent_free_attr(evnt_attr_list); 113*1991Sheppo goto done; 114*1991Sheppo } 115*1991Sheppo 116*1991Sheppo /* 117*1991Sheppo * Attach the attribute list to the event 118*1991Sheppo */ 119*1991Sheppo rv = sysevent_attach_attributes(ev, evnt_attr_list); 120*1991Sheppo if (rv != 0) { 121*1991Sheppo DR_DBG_ALL("generate_event: failed to add attr list for " 122*1991Sheppo "'%s' event\n", EC_DR); 123*1991Sheppo sysevent_free_attr(evnt_attr_list); 124*1991Sheppo goto done; 125*1991Sheppo } 126*1991Sheppo 127*1991Sheppo /* 128*1991Sheppo * Log the event 129*1991Sheppo */ 130*1991Sheppo rv = log_sysevent(ev, KM_NOSLEEP, &eid); 131*1991Sheppo if (rv != 0) { 132*1991Sheppo DR_DBG_ALL("generate_event: failed to log event (%d)\n", rv); 133*1991Sheppo } 134*1991Sheppo 135*1991Sheppo done: 136*1991Sheppo if (ev != NULL) 137*1991Sheppo sysevent_free(ev); 138*1991Sheppo } 139*1991Sheppo 140*1991Sheppo /* 141*1991Sheppo * Debugging Features 142*1991Sheppo */ 143*1991Sheppo #ifdef DEBUG 144*1991Sheppo 145*1991Sheppo uint_t dr_debug = 0x0; 146*1991Sheppo 147*1991Sheppo #define BYTESPERLINE 8 148*1991Sheppo #define LINEWIDTH ((BYTESPERLINE * 3) + (BYTESPERLINE + 2) + 1) 149*1991Sheppo #define ASCIIOFFSET ((BYTESPERLINE * 3) + 2) 150*1991Sheppo #define ISPRINT(c) ((c >= ' ') && (c <= '~')) 151*1991Sheppo 152*1991Sheppo /* 153*1991Sheppo * Output a buffer formatted with a set number of bytes on 154*1991Sheppo * each line. Append each line with the ASCII equivalent of 155*1991Sheppo * each byte if it falls within the printable ASCII range, 156*1991Sheppo * and '.' otherwise. 157*1991Sheppo */ 158*1991Sheppo void 159*1991Sheppo dr_dbg_dump_msg(void *buf, size_t len) 160*1991Sheppo { 161*1991Sheppo int i, j; 162*1991Sheppo char *msg = buf; 163*1991Sheppo char *curr; 164*1991Sheppo char *aoff; 165*1991Sheppo char line[LINEWIDTH]; 166*1991Sheppo 167*1991Sheppo /* abort if not debugging transport */ 168*1991Sheppo if (!(dr_debug & DR_DBG_FLAG_TRANS)) { 169*1991Sheppo return; 170*1991Sheppo } 171*1991Sheppo 172*1991Sheppo /* walk the buffer one line at a time */ 173*1991Sheppo for (i = 0; i < len; i += BYTESPERLINE) { 174*1991Sheppo 175*1991Sheppo bzero(line, LINEWIDTH); 176*1991Sheppo 177*1991Sheppo curr = line; 178*1991Sheppo aoff = line + ASCIIOFFSET; 179*1991Sheppo 180*1991Sheppo /* 181*1991Sheppo * Walk the bytes in the current line, storing 182*1991Sheppo * the hex value for the byte as well as the 183*1991Sheppo * ASCII representation in a temporary buffer. 184*1991Sheppo * All ASCII values are placed at the end of 185*1991Sheppo * the line. 186*1991Sheppo */ 187*1991Sheppo for (j = 0; (j < BYTESPERLINE) && ((i + j) < len); j++) { 188*1991Sheppo (void) sprintf(curr, " %02x", msg[i + j]); 189*1991Sheppo *aoff = (ISPRINT(msg[i + j])) ? msg[i + j] : '.'; 190*1991Sheppo curr += 3; 191*1991Sheppo aoff++; 192*1991Sheppo } 193*1991Sheppo 194*1991Sheppo /* 195*1991Sheppo * Fill in to the start of the ASCII translation 196*1991Sheppo * with spaces. This will only be necessary if 197*1991Sheppo * this is the last line and there are not enough 198*1991Sheppo * bytes to fill the whole line. 199*1991Sheppo */ 200*1991Sheppo while (curr != (line + ASCIIOFFSET)) 201*1991Sheppo *curr++ = ' '; 202*1991Sheppo 203*1991Sheppo DR_DBG_TRANS("%s\n", line); 204*1991Sheppo } 205*1991Sheppo } 206*1991Sheppo #endif /* DEBUG */ 207