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 /* 226070Srobj * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 233798Seschrock * Use is subject to license terms. 243798Seschrock */ 253798Seschrock 263798Seschrock #include <libipmi.h> 276070Srobj #include <stdio.h> 283798Seschrock #include <string.h> 293798Seschrock 303798Seschrock #include "ipmi_impl.h" 313798Seschrock 323798Seschrock ipmi_deviceid_t * 333798Seschrock ipmi_get_deviceid(ipmi_handle_t *ihp) 343798Seschrock { 353798Seschrock ipmi_cmd_t cmd, *resp; 366360Srobj uint16_t id_prod; 373798Seschrock 386070Srobj if (ihp->ih_deviceid != NULL) 396070Srobj return (ihp->ih_deviceid); 403798Seschrock 413798Seschrock cmd.ic_netfn = IPMI_NETFN_APP; 423798Seschrock cmd.ic_lun = 0; 433798Seschrock cmd.ic_cmd = IPMI_CMD_GET_DEVICEID; 443798Seschrock cmd.ic_data = NULL; 453798Seschrock cmd.ic_dlen = 0; 463798Seschrock 473798Seschrock if ((resp = ipmi_send(ihp, &cmd)) == NULL) 483798Seschrock return (NULL); 493798Seschrock 503798Seschrock if (resp->ic_dlen < sizeof (ipmi_deviceid_t)) { 513798Seschrock (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL); 523798Seschrock return (NULL); 533798Seschrock } 543798Seschrock 556070Srobj /* 566070Srobj * The devid response data may include additional data beyond the end of 576070Srobj * the normal structure, so we copy the entire response. 586070Srobj */ 596070Srobj if ((ihp->ih_deviceid = ipmi_alloc(ihp, resp->ic_dlen)) == NULL) 606070Srobj return (NULL); 616070Srobj 626070Srobj (void) memcpy(ihp->ih_deviceid, resp->ic_data, resp->ic_dlen); 636360Srobj id_prod = LE_IN16(&ihp->ih_deviceid->id_product); 646726Srobj (void) memcpy(&ihp->ih_deviceid->id_product, &id_prod, 656360Srobj sizeof (id_prod)); 666070Srobj ihp->ih_deviceid_len = resp->ic_dlen; 676070Srobj 686070Srobj return (ihp->ih_deviceid); 696070Srobj } 706070Srobj 716070Srobj /* 726070Srobj * Returns the firmware revision as a string. This does the work of converting 736070Srobj * the deviceid data into a human readable string (decoding the BCD values). 746070Srobj * It also encodes the fact that Sun ILOM includes the additional micro revision 756070Srobj * at the end of the deviceid information. 766070Srobj */ 776070Srobj const char * 786070Srobj ipmi_firmware_version(ipmi_handle_t *ihp) 796070Srobj { 806070Srobj ipmi_deviceid_t *dp; 816070Srobj uint8_t *auxrev; 826070Srobj size_t len; 836070Srobj char rev[128]; 846070Srobj int i; 856070Srobj 866070Srobj if (ihp->ih_firmware_rev != NULL) 876070Srobj return (ihp->ih_firmware_rev); 883798Seschrock 896070Srobj if ((dp = ipmi_get_deviceid(ihp)) == NULL) 906070Srobj return (NULL); 916070Srobj 926070Srobj /* 936070Srobj * Start with the major an minor revision numbers 946070Srobj */ 956070Srobj (void) snprintf(rev, sizeof (rev), "%d.%d", dp->id_firm_major, 966070Srobj ipmi_convert_bcd(dp->id_firm_minor)); 976070Srobj 986070Srobj if (ipmi_is_sun_ilom(dp) && 996070Srobj ihp->ih_deviceid_len >= sizeof (ipmi_deviceid_t) + 4) { 1006070Srobj /* 1016070Srobj * With Sun ILOM we have the micro revision at the end of the 1026070Srobj * deviceid. The first two bytes of the aux revision field are 1036070Srobj * the platform version and release version. 1046070Srobj */ 1056070Srobj auxrev = (uint8_t *)dp + sizeof (ipmi_deviceid_t); 1066070Srobj for (i = 0; i < 2; i++) { 1076070Srobj if (auxrev[i] == 0) 1086070Srobj continue; 1096070Srobj 1106070Srobj len = strlen(rev); 1116070Srobj (void) snprintf(rev + len, sizeof (rev) - len, ".%u", 1126070Srobj auxrev[i]); 1136070Srobj } 1146070Srobj } 1156070Srobj 1166070Srobj if ((ihp->ih_firmware_rev = ipmi_strdup(ihp, rev)) == NULL) 1176070Srobj return (NULL); 1186070Srobj 1196070Srobj return (ihp->ih_firmware_rev); 1203798Seschrock } 121*8339SEric.Schrock@Sun.COM 122*8339SEric.Schrock@Sun.COM ipmi_channel_info_t * 123*8339SEric.Schrock@Sun.COM ipmi_get_channel_info(ipmi_handle_t *ihp, int number) 124*8339SEric.Schrock@Sun.COM { 125*8339SEric.Schrock@Sun.COM ipmi_cmd_t cmd, *rsp; 126*8339SEric.Schrock@Sun.COM uint8_t channel; 127*8339SEric.Schrock@Sun.COM 128*8339SEric.Schrock@Sun.COM if (number > 0xF) { 129*8339SEric.Schrock@Sun.COM (void) ipmi_set_error(ihp, EIPMI_INVALID_REQUEST, NULL); 130*8339SEric.Schrock@Sun.COM return (NULL); 131*8339SEric.Schrock@Sun.COM } 132*8339SEric.Schrock@Sun.COM 133*8339SEric.Schrock@Sun.COM channel = (uint8_t)number; 134*8339SEric.Schrock@Sun.COM 135*8339SEric.Schrock@Sun.COM cmd.ic_netfn = IPMI_NETFN_APP; 136*8339SEric.Schrock@Sun.COM cmd.ic_lun = 0; 137*8339SEric.Schrock@Sun.COM cmd.ic_cmd = IPMI_CMD_GET_CHANNEL_INFO; 138*8339SEric.Schrock@Sun.COM cmd.ic_data = &channel; 139*8339SEric.Schrock@Sun.COM cmd.ic_dlen = sizeof (channel); 140*8339SEric.Schrock@Sun.COM 141*8339SEric.Schrock@Sun.COM if ((rsp = ipmi_send(ihp, &cmd)) == NULL) 142*8339SEric.Schrock@Sun.COM return (NULL); 143*8339SEric.Schrock@Sun.COM 144*8339SEric.Schrock@Sun.COM if (rsp->ic_dlen < sizeof (ipmi_channel_info_t)) { 145*8339SEric.Schrock@Sun.COM (void) ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL); 146*8339SEric.Schrock@Sun.COM return (NULL); 147*8339SEric.Schrock@Sun.COM } 148*8339SEric.Schrock@Sun.COM 149*8339SEric.Schrock@Sun.COM return (rsp->ic_data); 150*8339SEric.Schrock@Sun.COM } 151