1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <libipmi.h> 30 #include <stddef.h> 31 32 #include "ipmi_impl.h" 33 34 static int 35 check_sunoem(ipmi_handle_t *ihp) 36 { 37 ipmi_deviceid_t *devid; 38 39 if ((devid = ipmi_get_deviceid(ihp)) == NULL) 40 return (-1); 41 42 if (ipmi_devid_manufacturer(devid) != IPMI_OEM_SUN) 43 return (ipmi_set_error(ihp, EIPMI_INVALID_COMMAND, NULL)); 44 45 return (0); 46 } 47 48 static int 49 ipmi_send_sunoem_led_set(ipmi_handle_t *ihp, ipmi_cmd_sunoem_led_set_t *req) 50 { 51 ipmi_cmd_t cmd, *resp; 52 53 cmd.ic_netfn = IPMI_NETFN_OEM; 54 cmd.ic_cmd = IPMI_CMD_SUNOEM_LED_SET; 55 cmd.ic_lun = 0; 56 cmd.ic_data = req; 57 cmd.ic_dlen = sizeof (*req); 58 59 if ((resp = ipmi_send(ihp, &cmd)) == NULL) 60 return (-1); 61 62 if (resp->ic_dlen != 0) 63 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 64 65 return (0); 66 } 67 68 static int 69 ipmi_send_sunoem_led_get(ipmi_handle_t *ihp, ipmi_cmd_sunoem_led_get_t *req, 70 uint8_t *result) 71 { 72 ipmi_cmd_t cmd, *resp; 73 74 cmd.ic_netfn = IPMI_NETFN_OEM; 75 cmd.ic_cmd = IPMI_CMD_SUNOEM_LED_GET; 76 cmd.ic_lun = 0; 77 cmd.ic_data = req; 78 cmd.ic_dlen = sizeof (*req); 79 80 if ((resp = ipmi_send(ihp, &cmd)) == NULL) 81 return (-1); 82 83 if (resp->ic_dlen != 1) 84 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 85 86 *result = *((uint8_t *)resp->ic_data); 87 return (0); 88 } 89 90 int 91 ipmi_sunoem_led_set(ipmi_handle_t *ihp, ipmi_sdr_generic_locator_t *dev, 92 uint8_t mode) 93 { 94 ipmi_cmd_sunoem_led_set_t cmd = { 0 }; 95 96 if (check_sunoem(ihp) != 0) 97 return (-1); 98 99 cmd.ic_sls_devaddr = dev->is_gl_slaveaddr; 100 cmd.ic_sls_type = dev->is_gl_oem; 101 cmd.ic_sls_ctladdr = dev->is_gl_accessaddr; 102 cmd.ic_sls_hwinfo = dev->is_gl_oem; 103 cmd.ic_sls_mode = mode; 104 105 return (ipmi_send_sunoem_led_set(ihp, &cmd)); 106 } 107 108 int 109 ipmi_sunoem_led_get(ipmi_handle_t *ihp, ipmi_sdr_generic_locator_t *dev, 110 uint8_t *mode) 111 { 112 ipmi_cmd_sunoem_led_get_t cmd = { 0 }; 113 114 if (check_sunoem(ihp) != 0) 115 return (-1); 116 117 cmd.ic_slg_devaddr = dev->is_gl_slaveaddr; 118 cmd.ic_slg_type = dev->is_gl_oem; 119 cmd.ic_slg_ctladdr = dev->is_gl_accessaddr; 120 cmd.ic_slg_hwinfo = dev->is_gl_oem; 121 122 return (ipmi_send_sunoem_led_get(ihp, &cmd, mode)); 123 } 124 125 int 126 ipmi_sunoem_uptime(ipmi_handle_t *ihp, uint32_t *uptime, uint32_t *gen) 127 { 128 ipmi_cmd_t cmd, *resp; 129 uint8_t unused; 130 131 if (check_sunoem(ihp) != 0) 132 return (-1); 133 134 cmd.ic_netfn = IPMI_NETFN_OEM; 135 cmd.ic_lun = 0; 136 cmd.ic_cmd = IPMI_CMD_SUNOEM_UPTIME; 137 cmd.ic_dlen = sizeof (unused); 138 cmd.ic_data = &unused; 139 140 if ((resp = ipmi_send(ihp, &cmd)) == NULL) 141 return (-1); 142 143 if (resp->ic_dlen != 2 * sizeof (uint32_t)) 144 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 145 146 if (uptime) 147 *uptime = BE_32(((uint32_t *)resp->ic_data)[0]); 148 if (gen) 149 *gen = BE_32(((uint32_t *)resp->ic_data)[1]); 150 151 return (0); 152 } 153 154 int 155 ipmi_sunoem_update_fru(ipmi_handle_t *ihp, ipmi_sunoem_fru_t *req) 156 { 157 ipmi_cmd_t cmd, *resp; 158 159 if (check_sunoem(ihp) != 0) 160 return (-1); 161 162 switch (req->isf_type) { 163 case IPMI_SUNOEM_FRU_DIMM: 164 req->isf_datalen = sizeof (req->isf_data.dimm); 165 break; 166 167 case IPMI_SUNOEM_FRU_CPU: 168 req->isf_datalen = sizeof (req->isf_data.cpu); 169 break; 170 171 case IPMI_SUNOEM_FRU_BIOS: 172 req->isf_datalen = sizeof (req->isf_data.bios); 173 break; 174 175 case IPMI_SUNOEM_FRU_DISK: 176 req->isf_datalen = sizeof (req->isf_data.disk); 177 break; 178 } 179 180 cmd.ic_netfn = IPMI_NETFN_OEM; 181 cmd.ic_cmd = IPMI_CMD_SUNOEM_FRU_UPDATE; 182 cmd.ic_lun = 0; 183 cmd.ic_dlen = offsetof(ipmi_sunoem_fru_t, isf_data) + 184 req->isf_datalen; 185 cmd.ic_data = req; 186 187 if ((resp = ipmi_send(ihp, &cmd)) == NULL) 188 return (-1); 189 190 if (resp->ic_dlen != 0) 191 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 192 193 return (0); 194 } 195