13798Seschrock /* 23798Seschrock * CDDL HEADER START 33798Seschrock * 43798Seschrock * The contents of this file are subject to the terms of the 53798Seschrock * Common Development and Distribution License (the "License"). 63798Seschrock * You may not use this file except in compliance with the License. 73798Seschrock * 83798Seschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93798Seschrock * or http://www.opensolaris.org/os/licensing. 103798Seschrock * See the License for the specific language governing permissions 113798Seschrock * and limitations under the License. 123798Seschrock * 133798Seschrock * When distributing Covered Code, include this CDDL HEADER in each 143798Seschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153798Seschrock * If applicable, add the following below this CDDL HEADER, with the 163798Seschrock * fields enclosed by brackets "[]" replaced with your own identifying 173798Seschrock * information: Portions Copyright [yyyy] [name of copyright owner] 183798Seschrock * 193798Seschrock * CDDL HEADER END 203798Seschrock */ 213798Seschrock /* 22*11756SRobert.Johnston@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 233798Seschrock * Use is subject to license terms. 243798Seschrock */ 253798Seschrock 263798Seschrock #include <libipmi.h> 273798Seschrock #include <string.h> 283798Seschrock 293798Seschrock #include <sys/bmc_intf.h> 303798Seschrock 313798Seschrock #include "ipmi_impl.h" 323798Seschrock 333798Seschrock ipmi_handle_t * 34*11756SRobert.Johnston@Sun.COM ipmi_open(int *errp, char **msg, uint_t xport_type, nvlist_t *params) 353798Seschrock { 363798Seschrock ipmi_handle_t *ihp; 376070Srobj static char errmsg[48]; 383798Seschrock 393798Seschrock if (msg) 403798Seschrock *msg = NULL; 413798Seschrock 423798Seschrock if ((ihp = calloc(sizeof (ipmi_handle_t), 1)) == NULL) { 433798Seschrock *errp = EIPMI_NOMEM; 443798Seschrock if (msg) 453798Seschrock *msg = "memory allocation failure"; 463798Seschrock return (NULL); 473798Seschrock } 483798Seschrock 49*11756SRobert.Johnston@Sun.COM switch (xport_type) { 50*11756SRobert.Johnston@Sun.COM case IPMI_TRANSPORT_BMC: 51*11756SRobert.Johnston@Sun.COM ihp->ih_transport = &ipmi_transport_bmc; 52*11756SRobert.Johnston@Sun.COM break; 53*11756SRobert.Johnston@Sun.COM case IPMI_TRANSPORT_LAN: 54*11756SRobert.Johnston@Sun.COM ihp->ih_transport = &ipmi_transport_lan; 55*11756SRobert.Johnston@Sun.COM break; 56*11756SRobert.Johnston@Sun.COM default: 57*11756SRobert.Johnston@Sun.COM *msg = "invalid transport type specified"; 58*11756SRobert.Johnston@Sun.COM return (NULL); 59*11756SRobert.Johnston@Sun.COM } 603798Seschrock 613798Seschrock ihp->ih_retries = 3; 623798Seschrock 63*11756SRobert.Johnston@Sun.COM if ((ihp->ih_tdata = ihp->ih_transport->it_open(ihp, params)) == NULL || 646070Srobj ipmi_sdr_init(ihp) != 0 || ipmi_entity_init(ihp) != 0) { 653798Seschrock *errp = ihp->ih_errno; 663798Seschrock if (msg) { 676070Srobj (void) strncpy(errmsg, ipmi_errmsg(ihp), 47); 686070Srobj errmsg[47] = '\0'; 696070Srobj *msg = errmsg; 703798Seschrock } 713798Seschrock ipmi_close(ihp); 723798Seschrock return (NULL); 733798Seschrock } 743798Seschrock 753798Seschrock return (ihp); 763798Seschrock } 773798Seschrock 783798Seschrock void 793798Seschrock ipmi_close(ipmi_handle_t *ihp) 803798Seschrock { 813798Seschrock if (ihp->ih_transport && ihp->ih_tdata) 823798Seschrock ihp->ih_transport->it_close(ihp->ih_tdata); 836070Srobj ipmi_free(ihp, ihp->ih_deviceid); 846070Srobj ipmi_free(ihp, ihp->ih_firmware_rev); 855345Seschrock ipmi_user_clear(ihp); 866070Srobj ipmi_sdr_fini(ihp); 876070Srobj ipmi_entity_fini(ihp); 883798Seschrock free(ihp); 893798Seschrock } 903798Seschrock 913798Seschrock /* 923798Seschrock * See section 5.2 for a description of the completion codes. 933798Seschrock */ 943798Seschrock static struct ipmi_err_conv { 953798Seschrock int bmc_err; 963798Seschrock int ipmi_err; 973798Seschrock } ipmi_errtable[] = { 983798Seschrock { 0xC0, EIPMI_BUSY }, 993798Seschrock { 0xC1, EIPMI_INVALID_COMMAND }, 1003798Seschrock { 0xC2, EIPMI_INVALID_COMMAND }, 1013798Seschrock { 0xC3, EIPMI_COMMAND_TIMEOUT }, 1023798Seschrock { 0xC4, EIPMI_NOSPACE }, 1033798Seschrock { 0xC5, EIPMI_INVALID_RESERVATION }, 1043798Seschrock { 0xC6, EIPMI_INVALID_REQUEST }, 1053798Seschrock { 0xC7, EIPMI_INVALID_REQUEST }, 1063798Seschrock { 0xC8, EIPMI_INVALID_REQUEST }, 1073798Seschrock { 0xC9, EIPMI_INVALID_REQUEST }, 1083798Seschrock { 0xCA, EIPMI_DATA_LENGTH_EXCEEDED }, 1093798Seschrock { 0xCB, EIPMI_NOT_PRESENT }, 1103798Seschrock { 0xCC, EIPMI_INVALID_REQUEST }, 1113798Seschrock { 0xCD, EIPMI_INVALID_COMMAND }, 1123798Seschrock { 0xCE, EIPMI_UNAVAILABLE }, 1133798Seschrock { 0xCF, EIPMI_UNAVAILABLE }, 1143798Seschrock { 0xD0, EIPMI_BUSY }, 1153798Seschrock { 0xD1, EIPMI_BUSY }, 1163798Seschrock { 0xD2, EIPMI_BUSY }, 1173798Seschrock { 0xD3, EIPMI_NOT_PRESENT }, 1183798Seschrock { 0xD4, EIPMI_ACCESS }, 1193798Seschrock { 0xD5, EIPMI_UNAVAILABLE }, 1203798Seschrock { 0xD6, EIPMI_UNAVAILABLE }, 1213798Seschrock { 0xFF, EIPMI_UNSPECIFIED }, 1223798Seschrock { BMC_IPMI_OEM_FAILURE_SENDBMC, EIPMI_SEND_FAILED }, 1233798Seschrock }; 1243798Seschrock 1253798Seschrock #define IPMI_ERROR_COUNT \ 1263798Seschrock (sizeof (ipmi_errtable) / sizeof (ipmi_errtable[0])) 1273798Seschrock 1283798Seschrock ipmi_cmd_t * 1293798Seschrock ipmi_send(ipmi_handle_t *ihp, ipmi_cmd_t *cmd) 1303798Seschrock { 1313798Seschrock int i; 1323798Seschrock 1333798Seschrock if (ihp->ih_transport->it_send(ihp->ih_tdata, cmd, &ihp->ih_response, 1348339SEric.Schrock@Sun.COM &ihp->ih_completion) != 0) 1353798Seschrock return (NULL); 1363798Seschrock 1378339SEric.Schrock@Sun.COM if (ihp->ih_completion != 0) { 1383798Seschrock for (i = 0; i < IPMI_ERROR_COUNT; i++) { 1398339SEric.Schrock@Sun.COM if (ihp->ih_completion == ipmi_errtable[i].bmc_err) { 1403798Seschrock (void) ipmi_set_error(ihp, 1413798Seschrock ipmi_errtable[i].ipmi_err, 1428339SEric.Schrock@Sun.COM "IPMI completion code 0x%x", 1438339SEric.Schrock@Sun.COM ihp->ih_completion); 1443798Seschrock return (NULL); 1453798Seschrock } 1463798Seschrock } 1473798Seschrock 1483798Seschrock (void) ipmi_set_error(ihp, EIPMI_UNKNOWN, 1498339SEric.Schrock@Sun.COM "IPMI completion code 0x%x", ihp->ih_completion); 1503798Seschrock return (NULL); 1513798Seschrock } 1523798Seschrock 1533798Seschrock return (&ihp->ih_response); 1543798Seschrock } 155