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*12315SRobert.Johnston@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 233798Seschrock */ 243798Seschrock 253798Seschrock #include <libipmi.h> 266070Srobj #include <stdio.h> 273798Seschrock #include <string.h> 283798Seschrock 293798Seschrock #include "ipmi_impl.h" 303798Seschrock 313798Seschrock ipmi_deviceid_t * 323798Seschrock ipmi_get_deviceid(ipmi_handle_t *ihp) 333798Seschrock { 343798Seschrock ipmi_cmd_t cmd, *resp; 356360Srobj uint16_t id_prod; 363798Seschrock 376070Srobj if (ihp->ih_deviceid != NULL) 386070Srobj return (ihp->ih_deviceid); 393798Seschrock 403798Seschrock cmd.ic_netfn = IPMI_NETFN_APP; 413798Seschrock cmd.ic_lun = 0; 423798Seschrock cmd.ic_cmd = IPMI_CMD_GET_DEVICEID; 433798Seschrock cmd.ic_data = NULL; 443798Seschrock cmd.ic_dlen = 0; 453798Seschrock 463798Seschrock if ((resp = ipmi_send(ihp, &cmd)) == NULL) 473798Seschrock return (NULL); 483798Seschrock 493798Seschrock if (resp->ic_dlen < sizeof (ipmi_deviceid_t)) { 503798Seschrock (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL); 513798Seschrock return (NULL); 523798Seschrock } 533798Seschrock 546070Srobj /* 556070Srobj * The devid response data may include additional data beyond the end of 566070Srobj * the normal structure, so we copy the entire response. 576070Srobj */ 586070Srobj if ((ihp->ih_deviceid = ipmi_alloc(ihp, resp->ic_dlen)) == NULL) 596070Srobj return (NULL); 606070Srobj 616070Srobj (void) memcpy(ihp->ih_deviceid, resp->ic_data, resp->ic_dlen); 626360Srobj id_prod = LE_IN16(&ihp->ih_deviceid->id_product); 636726Srobj (void) memcpy(&ihp->ih_deviceid->id_product, &id_prod, 646360Srobj sizeof (id_prod)); 656070Srobj ihp->ih_deviceid_len = resp->ic_dlen; 666070Srobj 676070Srobj return (ihp->ih_deviceid); 686070Srobj } 696070Srobj 706070Srobj /* 716070Srobj * Returns the firmware revision as a string. This does the work of converting 726070Srobj * the deviceid data into a human readable string (decoding the BCD values). 736070Srobj * It also encodes the fact that Sun ILOM includes the additional micro revision 746070Srobj * at the end of the deviceid information. 756070Srobj */ 766070Srobj const char * 776070Srobj ipmi_firmware_version(ipmi_handle_t *ihp) 786070Srobj { 796070Srobj ipmi_deviceid_t *dp; 806070Srobj uint8_t *auxrev; 816070Srobj size_t len; 826070Srobj char rev[128]; 836070Srobj int i; 846070Srobj 856070Srobj if (ihp->ih_firmware_rev != NULL) 866070Srobj return (ihp->ih_firmware_rev); 873798Seschrock 886070Srobj if ((dp = ipmi_get_deviceid(ihp)) == NULL) 896070Srobj return (NULL); 906070Srobj 916070Srobj /* 926070Srobj * Start with the major an minor revision numbers 936070Srobj */ 946070Srobj (void) snprintf(rev, sizeof (rev), "%d.%d", dp->id_firm_major, 956070Srobj ipmi_convert_bcd(dp->id_firm_minor)); 966070Srobj 976070Srobj if (ipmi_is_sun_ilom(dp) && 986070Srobj ihp->ih_deviceid_len >= sizeof (ipmi_deviceid_t) + 4) { 996070Srobj /* 1006070Srobj * With Sun ILOM we have the micro revision at the end of the 1016070Srobj * deviceid. The first two bytes of the aux revision field are 1026070Srobj * the platform version and release version. 1036070Srobj */ 1046070Srobj auxrev = (uint8_t *)dp + sizeof (ipmi_deviceid_t); 1056070Srobj for (i = 0; i < 2; i++) { 1066070Srobj if (auxrev[i] == 0) 1076070Srobj continue; 1086070Srobj 1096070Srobj len = strlen(rev); 1106070Srobj (void) snprintf(rev + len, sizeof (rev) - len, ".%u", 1116070Srobj auxrev[i]); 1126070Srobj } 1136070Srobj } 1146070Srobj 1156070Srobj if ((ihp->ih_firmware_rev = ipmi_strdup(ihp, rev)) == NULL) 1166070Srobj return (NULL); 1176070Srobj 1186070Srobj return (ihp->ih_firmware_rev); 1193798Seschrock } 1208339SEric.Schrock@Sun.COM 12111756SRobert.Johnston@Sun.COM /* 12211756SRobert.Johnston@Sun.COM * IPMI Get Channel Authentication Capabilities Command 12311756SRobert.Johnston@Sun.COM * See Section 22.13 12411756SRobert.Johnston@Sun.COM * 12511756SRobert.Johnston@Sun.COM * Caller is responsible for free'ing returned ipmi_channel_auth_caps_t 12611756SRobert.Johnston@Sun.COM */ 12711756SRobert.Johnston@Sun.COM ipmi_channel_auth_caps_t * 12811756SRobert.Johnston@Sun.COM ipmi_get_channel_auth_caps(ipmi_handle_t *ihp, uint8_t channel, uint8_t priv) 12911756SRobert.Johnston@Sun.COM { 13011756SRobert.Johnston@Sun.COM ipmi_cmd_t cmd, *resp; 13111756SRobert.Johnston@Sun.COM uint8_t msg_data[2]; 13211756SRobert.Johnston@Sun.COM ipmi_channel_auth_caps_t *caps; 13311756SRobert.Johnston@Sun.COM 13411756SRobert.Johnston@Sun.COM if (channel > 0xF) { 13511756SRobert.Johnston@Sun.COM (void) ipmi_set_error(ihp, EIPMI_INVALID_REQUEST, NULL); 13611756SRobert.Johnston@Sun.COM return (NULL); 13711756SRobert.Johnston@Sun.COM } 13811756SRobert.Johnston@Sun.COM 13911756SRobert.Johnston@Sun.COM msg_data[0] = channel; 14011756SRobert.Johnston@Sun.COM msg_data[1] = priv; 14111756SRobert.Johnston@Sun.COM 14211756SRobert.Johnston@Sun.COM cmd.ic_netfn = IPMI_NETFN_APP; 14311756SRobert.Johnston@Sun.COM cmd.ic_cmd = IPMI_CMD_GET_CHANNEL_AUTH_CAPS; 14411756SRobert.Johnston@Sun.COM cmd.ic_data = msg_data; 14511756SRobert.Johnston@Sun.COM cmd.ic_dlen = sizeof (msg_data); 14611756SRobert.Johnston@Sun.COM cmd.ic_lun = 0; 14711756SRobert.Johnston@Sun.COM 14811756SRobert.Johnston@Sun.COM if ((resp = ipmi_send(ihp, &cmd)) == NULL) 14911756SRobert.Johnston@Sun.COM return (NULL); 15011756SRobert.Johnston@Sun.COM 15111756SRobert.Johnston@Sun.COM if (resp->ic_dlen < sizeof (ipmi_channel_auth_caps_t)) { 15211756SRobert.Johnston@Sun.COM (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL); 15311756SRobert.Johnston@Sun.COM return (NULL); 15411756SRobert.Johnston@Sun.COM } 15511756SRobert.Johnston@Sun.COM 15611756SRobert.Johnston@Sun.COM if ((caps = ipmi_alloc(ihp, sizeof (ipmi_channel_auth_caps_t))) 15711756SRobert.Johnston@Sun.COM == NULL) 15811756SRobert.Johnston@Sun.COM /* ipmi errno set */ 15911756SRobert.Johnston@Sun.COM return (NULL); 16011756SRobert.Johnston@Sun.COM 16111756SRobert.Johnston@Sun.COM (void) memcpy(caps, resp->ic_data, sizeof (ipmi_channel_auth_caps_t)); 16211756SRobert.Johnston@Sun.COM 16311756SRobert.Johnston@Sun.COM return (caps); 16411756SRobert.Johnston@Sun.COM } 16511756SRobert.Johnston@Sun.COM 1668339SEric.Schrock@Sun.COM ipmi_channel_info_t * 1678339SEric.Schrock@Sun.COM ipmi_get_channel_info(ipmi_handle_t *ihp, int number) 1688339SEric.Schrock@Sun.COM { 1698339SEric.Schrock@Sun.COM ipmi_cmd_t cmd, *rsp; 1708339SEric.Schrock@Sun.COM uint8_t channel; 1718339SEric.Schrock@Sun.COM 1728339SEric.Schrock@Sun.COM if (number > 0xF) { 1738339SEric.Schrock@Sun.COM (void) ipmi_set_error(ihp, EIPMI_INVALID_REQUEST, NULL); 1748339SEric.Schrock@Sun.COM return (NULL); 1758339SEric.Schrock@Sun.COM } 1768339SEric.Schrock@Sun.COM 1778339SEric.Schrock@Sun.COM channel = (uint8_t)number; 1788339SEric.Schrock@Sun.COM 1798339SEric.Schrock@Sun.COM cmd.ic_netfn = IPMI_NETFN_APP; 1808339SEric.Schrock@Sun.COM cmd.ic_lun = 0; 1818339SEric.Schrock@Sun.COM cmd.ic_cmd = IPMI_CMD_GET_CHANNEL_INFO; 1828339SEric.Schrock@Sun.COM cmd.ic_data = &channel; 1838339SEric.Schrock@Sun.COM cmd.ic_dlen = sizeof (channel); 1848339SEric.Schrock@Sun.COM 1858339SEric.Schrock@Sun.COM if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 1868339SEric.Schrock@Sun.COM return (NULL); 1878339SEric.Schrock@Sun.COM 1888339SEric.Schrock@Sun.COM if (rsp->ic_dlen < sizeof (ipmi_channel_info_t)) { 1898339SEric.Schrock@Sun.COM (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL); 1908339SEric.Schrock@Sun.COM return (NULL); 1918339SEric.Schrock@Sun.COM } 1928339SEric.Schrock@Sun.COM 1938339SEric.Schrock@Sun.COM return (rsp->ic_data); 1948339SEric.Schrock@Sun.COM } 195*12315SRobert.Johnston@Sun.COM 196*12315SRobert.Johnston@Sun.COM /* 197*12315SRobert.Johnston@Sun.COM * IPMI Chassis Identify Command 198*12315SRobert.Johnston@Sun.COM * See Section 28.5 199*12315SRobert.Johnston@Sun.COM */ 200*12315SRobert.Johnston@Sun.COM int 201*12315SRobert.Johnston@Sun.COM ipmi_chassis_identify(ipmi_handle_t *ihp, boolean_t enable) 202*12315SRobert.Johnston@Sun.COM { 203*12315SRobert.Johnston@Sun.COM ipmi_cmd_t cmd; 204*12315SRobert.Johnston@Sun.COM uint8_t msg_data[2]; 205*12315SRobert.Johnston@Sun.COM 206*12315SRobert.Johnston@Sun.COM if (enable) { 207*12315SRobert.Johnston@Sun.COM msg_data[0] = 0; 208*12315SRobert.Johnston@Sun.COM msg_data[1] = 1; 209*12315SRobert.Johnston@Sun.COM } else { 210*12315SRobert.Johnston@Sun.COM msg_data[0] = 0; 211*12315SRobert.Johnston@Sun.COM msg_data[1] = 0; 212*12315SRobert.Johnston@Sun.COM } 213*12315SRobert.Johnston@Sun.COM 214*12315SRobert.Johnston@Sun.COM cmd.ic_netfn = IPMI_NETFN_CHASSIS; 215*12315SRobert.Johnston@Sun.COM cmd.ic_cmd = IPMI_CMD_CHASSIS_IDENTIFY; 216*12315SRobert.Johnston@Sun.COM cmd.ic_data = msg_data; 217*12315SRobert.Johnston@Sun.COM cmd.ic_dlen = sizeof (msg_data); 218*12315SRobert.Johnston@Sun.COM cmd.ic_lun = 0; 219*12315SRobert.Johnston@Sun.COM 220*12315SRobert.Johnston@Sun.COM if (ipmi_send(ihp, &cmd) == NULL) 221*12315SRobert.Johnston@Sun.COM return (-1); 222*12315SRobert.Johnston@Sun.COM 223*12315SRobert.Johnston@Sun.COM return (0); 224*12315SRobert.Johnston@Sun.COM } 225