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_slaveaddr = dev->is_gl_slaveaddr; 100 cmd.ic_sls_channel_msb = dev->is_gl_channel_msb; 101 cmd.ic_sls_type = dev->is_gl_oem; 102 cmd.ic_sls_accessaddr = dev->is_gl_accessaddr; 103 cmd.ic_sls_hwinfo = dev->is_gl_oem; 104 cmd.ic_sls_mode = mode; 105 106 return (ipmi_send_sunoem_led_set(ihp, &cmd)); 107 } 108 109 int 110 ipmi_sunoem_led_get(ipmi_handle_t *ihp, ipmi_sdr_generic_locator_t *dev, 111 uint8_t *mode) 112 { 113 ipmi_cmd_sunoem_led_get_t cmd = { 0 }; 114 115 if (check_sunoem(ihp) != 0) 116 return (-1); 117 118 cmd.ic_slg_slaveaddr = dev->is_gl_slaveaddr; 119 cmd.ic_slg_channel_msb = dev->is_gl_channel_msb; 120 cmd.ic_slg_type = dev->is_gl_oem; 121 cmd.ic_slg_accessaddr = dev->is_gl_accessaddr; 122 cmd.ic_slg_hwinfo = dev->is_gl_oem; 123 124 return (ipmi_send_sunoem_led_get(ihp, &cmd, mode)); 125 } 126 127 int 128 ipmi_sunoem_uptime(ipmi_handle_t *ihp, uint32_t *uptime, uint32_t *gen) 129 { 130 ipmi_cmd_t cmd, *resp; 131 uint8_t unused; 132 133 if (check_sunoem(ihp) != 0) 134 return (-1); 135 136 cmd.ic_netfn = IPMI_NETFN_OEM; 137 cmd.ic_lun = 0; 138 cmd.ic_cmd = IPMI_CMD_SUNOEM_UPTIME; 139 cmd.ic_dlen = sizeof (unused); 140 cmd.ic_data = &unused; 141 142 if ((resp = ipmi_send(ihp, &cmd)) == NULL) 143 return (-1); 144 145 if (resp->ic_dlen != 2 * sizeof (uint32_t)) 146 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 147 148 if (uptime) 149 *uptime = BE_32(((uint32_t *)resp->ic_data)[0]); 150 if (gen) 151 *gen = BE_32(((uint32_t *)resp->ic_data)[1]); 152 153 return (0); 154 } 155 156 int 157 ipmi_sunoem_update_fru(ipmi_handle_t *ihp, ipmi_sunoem_fru_t *req) 158 { 159 ipmi_cmd_t cmd, *resp; 160 161 if (check_sunoem(ihp) != 0) 162 return (-1); 163 164 switch (req->isf_type) { 165 case IPMI_SUNOEM_FRU_DIMM: 166 req->isf_datalen = sizeof (req->isf_data.dimm); 167 break; 168 169 case IPMI_SUNOEM_FRU_CPU: 170 req->isf_datalen = sizeof (req->isf_data.cpu); 171 break; 172 173 case IPMI_SUNOEM_FRU_BIOS: 174 req->isf_datalen = sizeof (req->isf_data.bios); 175 break; 176 177 case IPMI_SUNOEM_FRU_DISK: 178 req->isf_datalen = sizeof (req->isf_data.disk); 179 break; 180 } 181 182 cmd.ic_netfn = IPMI_NETFN_OEM; 183 cmd.ic_cmd = IPMI_CMD_SUNOEM_FRU_UPDATE; 184 cmd.ic_lun = 0; 185 cmd.ic_dlen = offsetof(ipmi_sunoem_fru_t, isf_data) + 186 req->isf_datalen; 187 cmd.ic_data = req; 188 189 if ((resp = ipmi_send(ihp, &cmd)) == NULL) 190 return (-1); 191 192 if (resp->ic_dlen != 0) 193 return (ipmi_set_error(ihp, EIPMI_BAD_RESPONSE_LENGTH, NULL)); 194 195 return (0); 196 } 197