1*3798Seschrock /* 2*3798Seschrock * CDDL HEADER START 3*3798Seschrock * 4*3798Seschrock * The contents of this file are subject to the terms of the 5*3798Seschrock * Common Development and Distribution License (the "License"). 6*3798Seschrock * You may not use this file except in compliance with the License. 7*3798Seschrock * 8*3798Seschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*3798Seschrock * or http://www.opensolaris.org/os/licensing. 10*3798Seschrock * See the License for the specific language governing permissions 11*3798Seschrock * and limitations under the License. 12*3798Seschrock * 13*3798Seschrock * When distributing Covered Code, include this CDDL HEADER in each 14*3798Seschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*3798Seschrock * If applicable, add the following below this CDDL HEADER, with the 16*3798Seschrock * fields enclosed by brackets "[]" replaced with your own identifying 17*3798Seschrock * information: Portions Copyright [yyyy] [name of copyright owner] 18*3798Seschrock * 19*3798Seschrock * CDDL HEADER END 20*3798Seschrock */ 21*3798Seschrock /* 22*3798Seschrock * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*3798Seschrock * Use is subject to license terms. 24*3798Seschrock */ 25*3798Seschrock 26*3798Seschrock #pragma ident "%Z%%M% %I% %E% SMI" 27*3798Seschrock 28*3798Seschrock #include <libipmi.h> 29*3798Seschrock #include <stdio.h> 30*3798Seschrock #include <stdlib.h> 31*3798Seschrock #include <string.h> 32*3798Seschrock #include <stdarg.h> 33*3798Seschrock 34*3798Seschrock #include "ipmi_impl.h" 35*3798Seschrock 36*3798Seschrock /* 37*3798Seschrock * Error handling 38*3798Seschrock */ 39*3798Seschrock int 40*3798Seschrock ipmi_set_error(ipmi_handle_t *ihp, int error, const char *fmt, ...) 41*3798Seschrock { 42*3798Seschrock va_list ap; 43*3798Seschrock 44*3798Seschrock va_start(ap, fmt); 45*3798Seschrock 46*3798Seschrock ihp->ih_errno = error; 47*3798Seschrock if (fmt == NULL) 48*3798Seschrock ihp->ih_errmsg[0] = '\0'; 49*3798Seschrock else 50*3798Seschrock (void) vsnprintf(ihp->ih_errmsg, sizeof (ihp->ih_errmsg), 51*3798Seschrock fmt, ap); 52*3798Seschrock va_end(ap); 53*3798Seschrock 54*3798Seschrock return (-1); 55*3798Seschrock } 56*3798Seschrock 57*3798Seschrock int 58*3798Seschrock ipmi_errno(ipmi_handle_t *ihp) 59*3798Seschrock { 60*3798Seschrock return (ihp->ih_errno); 61*3798Seschrock } 62*3798Seschrock 63*3798Seschrock static struct { 64*3798Seschrock int err; 65*3798Seschrock const char *msg; 66*3798Seschrock } errno_table[] = { 67*3798Seschrock { EIPMI_NOMEM, "memory allocation failure" }, 68*3798Seschrock { EIPMI_BMC_OPEN_FAILED, "failed to open /dev/bmc" }, 69*3798Seschrock { EIPMI_BMC_PUTMSG, "failed to send message to /dev/bmc" }, 70*3798Seschrock { EIPMI_BMC_GETMSG, 71*3798Seschrock "failed to read response from /dev/bmc" }, 72*3798Seschrock { EIPMI_BMC_RESPONSE, 73*3798Seschrock "failed to read response from /dev/bmc" }, 74*3798Seschrock { EIPMI_INVALID_COMMAND, "invalid command" }, 75*3798Seschrock { EIPMI_COMMAND_TIMEOUT, "command timed out" }, 76*3798Seschrock { EIPMI_DATA_LENGTH_EXCEEDED, "maximum data length exceeded" }, 77*3798Seschrock { EIPMI_SEND_FAILED, "failed to send BMC request" }, 78*3798Seschrock { EIPMI_UNSPECIFIED, "unspecified BMC error" }, 79*3798Seschrock { EIPMI_BAD_RESPONSE_LENGTH, 80*3798Seschrock "unexpected command response data length" }, 81*3798Seschrock { EIPMI_INVALID_RESERVATION, "invalid or cancelled reservation" }, 82*3798Seschrock { EIPMI_NOT_PRESENT, "request entity not present" }, 83*3798Seschrock { EIPMI_INVALID_REQUEST, "malformed request data" }, 84*3798Seschrock { EIPMI_BUSY, "service processor is busy" }, 85*3798Seschrock { EIPMI_NOSPACE, "service processor is out of space" }, 86*3798Seschrock { EIPMI_UNAVAILABLE, "service processor is unavailable" }, 87*3798Seschrock { EIPMI_ACCESS, "insufficient privileges" } 88*3798Seschrock }; 89*3798Seschrock 90*3798Seschrock /* ARGSUSED */ 91*3798Seschrock const char * 92*3798Seschrock ipmi_errmsg(ipmi_handle_t *ihp) 93*3798Seschrock { 94*3798Seschrock int i; 95*3798Seschrock const char *str; 96*3798Seschrock 97*3798Seschrock str = NULL; 98*3798Seschrock for (i = 0; i < sizeof (errno_table) / sizeof (errno_table[0]); i++) { 99*3798Seschrock if (errno_table[i].err == ihp->ih_errno) { 100*3798Seschrock str = errno_table[i].msg; 101*3798Seschrock break; 102*3798Seschrock } 103*3798Seschrock } 104*3798Seschrock 105*3798Seschrock if (str == NULL && (str = strerror(ihp->ih_errno)) == NULL) 106*3798Seschrock str = "unknown failure"; 107*3798Seschrock 108*3798Seschrock if (ihp->ih_errmsg[0] == '\0') 109*3798Seschrock return (str); 110*3798Seschrock 111*3798Seschrock (void) snprintf(ihp->ih_errbuf, sizeof (ihp->ih_errbuf), 112*3798Seschrock "%s: %s", str, ihp->ih_errmsg); 113*3798Seschrock return (ihp->ih_errbuf); 114*3798Seschrock } 115*3798Seschrock 116*3798Seschrock /* 117*3798Seschrock * Memory allocation 118*3798Seschrock */ 119*3798Seschrock 120*3798Seschrock void * 121*3798Seschrock ipmi_alloc(ipmi_handle_t *ihp, size_t size) 122*3798Seschrock { 123*3798Seschrock void *ptr; 124*3798Seschrock 125*3798Seschrock if ((ptr = malloc(size)) == NULL) 126*3798Seschrock (void) ipmi_set_error(ihp, EIPMI_NOMEM, NULL); 127*3798Seschrock 128*3798Seschrock return (ptr); 129*3798Seschrock } 130*3798Seschrock 131*3798Seschrock void * 132*3798Seschrock ipmi_zalloc(ipmi_handle_t *ihp, size_t size) 133*3798Seschrock { 134*3798Seschrock void *ptr; 135*3798Seschrock 136*3798Seschrock if ((ptr = calloc(size, 1)) == NULL) 137*3798Seschrock (void) ipmi_set_error(ihp, EIPMI_NOMEM, NULL); 138*3798Seschrock 139*3798Seschrock return (ptr); 140*3798Seschrock } 141*3798Seschrock 142*3798Seschrock /* ARGSUSED */ 143*3798Seschrock void 144*3798Seschrock ipmi_free(ipmi_handle_t *ihp, void *ptr) 145*3798Seschrock { 146*3798Seschrock free(ptr); 147*3798Seschrock } 148