1 /* 2 * ipmi_control.h 3 * 4 * MontaVista IPMI interface for dealing with controls 5 * 6 * Author: MontaVista Software, Inc. 7 * Corey Minyard <minyard@mvista.com> 8 * source@mvista.com 9 * 10 * Copyright 2002,2003 MontaVista Software Inc. 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU Lesser General Public License 14 * as published by the Free Software Foundation; either version 2 of 15 * the License, or (at your option) any later version. 16 * 17 * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * You should have received a copy of the GNU Lesser General Public 30 * License along with this program; if not, write to the Free 31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 32 */ 33 34 #ifndef OPENIPMI_CONTROL_H 35 #define OPENIPMI_CONTROL_H 36 37 #include <OpenIPMI/ipmi_types.h> 38 #include <OpenIPMI/ipmi_addr.h> 39 40 /* The abstract type for controls. */ 41 typedef struct ipmi_control_info_s ipmi_control_info_t; 42 43 /* Allocate a repository for holding controls for an MC. */ 44 int ipmi_controls_alloc(ipmi_mc_t *mc, ipmi_control_info_t **new_controls); 45 46 /* Destroy a control repository and all the controls in it. */ 47 int ipmi_controls_destroy(ipmi_control_info_t *controls); 48 49 /* Must be called with the i_ipmi_domain_entity_lock() held. */ 50 int i_ipmi_control_get(ipmi_control_t *control); 51 52 /* Must be called with no locks held. */ 53 void i_ipmi_control_put(ipmi_control_t *control); 54 55 /* Return the number of controls in the data structure. */ 56 unsigned int ipmi_controls_get_count(ipmi_control_info_t *controls); 57 58 /* Operations and callbacks for control operations. Operations on a 59 control that can be delayed should be serialized (to avoid user 60 confusion and for handling multi-part operations properly), thus 61 each control has an operation queue, only one operation at a time 62 may be running. If you want to do an operation that requires 63 sending a message and getting a response, you must put that 64 operation into the opq. When the handler you registered in the opq 65 is called, you can actually perform the operation. When your 66 operation completes (no matter what, you must call it, even if the 67 operation fails), you must call ipmi_control_opq_done. The control 68 will be locked properly for your callback. To handle the control 69 locking for you for command responses, you can send the message 70 with ipmi_control_send_command, it will return the response when it 71 comes in to your handler with the control locked. */ 72 73 typedef void (*ipmi_control_rsp_cb)(ipmi_control_t *control, 74 int err, 75 ipmi_msg_t *rsp, 76 void *cb_data); 77 78 typedef struct ipmi_control_op_info_s 79 { 80 ipmi_control_id_t __control_id; 81 ipmi_control_t *__control; 82 void *__cb_data; 83 ipmi_control_op_cb __handler; 84 ipmi_control_rsp_cb __rsp_handler; 85 ipmi_msg_t *__rsp; 86 } ipmi_control_op_info_t; 87 88 /* Add an operation to the control operation queue. If nothing is in 89 the operation queue, the handler will be performed immediately. If 90 something else is currently being operated on, the operation will 91 be queued until other operations before it have been completed. 92 Then the handler will be called. */ 93 int ipmi_control_add_opq(ipmi_control_t *control, 94 ipmi_control_op_cb handler, 95 ipmi_control_op_info_t *info, 96 void *cb_data); 97 98 /* When an operation is completed (even if it fails), this *MUST* be 99 called to cause the next operation to run. */ 100 void ipmi_control_opq_done(ipmi_control_t *control); 101 102 /* Send an IPMI command to a specific MC. The response handler will 103 be called with the control locked. */ 104 int ipmi_control_send_command(ipmi_control_t *control, 105 ipmi_mc_t *mc, 106 unsigned int lun, 107 ipmi_msg_t *msg, 108 ipmi_control_rsp_cb handler, 109 ipmi_control_op_info_t *info, 110 void *cb_data); 111 112 /* Send an IPMI command to a specific address on the BMC. This way, 113 if you don't have an MC to represent the address, you can still 114 send the command. The response handler will be called with the 115 control locked. */ 116 int ipmi_control_send_command_addr(ipmi_domain_t *domain, 117 ipmi_control_t *control, 118 ipmi_addr_t *addr, 119 unsigned int addr_len, 120 ipmi_msg_t *msg, 121 ipmi_control_rsp_cb handler, 122 ipmi_control_op_info_t *info, 123 void *cb_data); 124 125 /* Set this if the control should be ignored for presence handling. */ 126 void ipmi_control_set_ignore_for_presence(ipmi_control_t *control, int ignore); 127 int ipmi_control_get_ignore_for_presence(ipmi_control_t *control); 128 129 130 /* Allocate a control, it will not be associated with anything yet. */ 131 int ipmi_control_alloc_nonstandard(ipmi_control_t **new_control); 132 133 /* Destroy a control. */ 134 int ipmi_control_destroy(ipmi_control_t *control); 135 136 typedef void (*ipmi_control_destroy_cb)(ipmi_control_t *control, 137 void *cb_data); 138 /* Add a control for the given MC and put it into the given entity. 139 Note that control will NOT appear as owned by the MC, the MC is 140 used for the OS handler and such. The source_mc is used to show 141 which MC "owns" the creation of the control, and may be NULL if the 142 control is presumed to come from the "main" SDR repository. */ 143 int ipmi_control_add_nonstandard( 144 ipmi_mc_t *mc, 145 ipmi_mc_t *source_mc, 146 ipmi_control_t *control, 147 unsigned int num, 148 ipmi_entity_t *ent, 149 ipmi_control_destroy_cb destroy_handler, 150 void *destroy_handler_cb_data); 151 152 typedef int (*ipmi_control_set_val_cb)(ipmi_control_t *control, 153 int *val, 154 ipmi_control_op_cb handler, 155 void *cb_data); 156 157 typedef int (*ipmi_control_get_val_cb)(ipmi_control_t *control, 158 ipmi_control_val_cb handler, 159 void *cb_data); 160 161 typedef int (*ipmi_control_set_display_string_cb)(ipmi_control_t *control, 162 unsigned int start_row, 163 unsigned int start_column, 164 char *str, 165 unsigned int len, 166 ipmi_control_op_cb handler, 167 void *cb_data); 168 169 typedef int (*ipmi_control_get_display_string_cb)(ipmi_control_t *control, 170 unsigned int start_row, 171 unsigned int start_column, 172 unsigned int len, 173 ipmi_control_str_cb handler, 174 void *cb_data); 175 typedef int (*ipmi_control_identifier_get_val_cb)( 176 ipmi_control_t *control, 177 ipmi_control_identifier_val_cb handler, 178 void *cb_data); 179 180 typedef int (*ipmi_control_identifier_set_val_cb)(ipmi_control_t *control, 181 unsigned char *val, 182 int length, 183 ipmi_control_op_cb handler, 184 void *cb_data); 185 186 typedef int (*ipmi_control_set_light_cb)(ipmi_control_t *control, 187 ipmi_light_setting_t *settings, 188 ipmi_control_op_cb handler, 189 void *cb_data); 190 typedef int (*ipmi_control_get_light_cb)(ipmi_control_t *control, 191 ipmi_light_settings_cb handler, 192 void *cb_data); 193 194 typedef struct ipmi_control_cbs_s 195 { 196 ipmi_control_set_val_cb set_val; 197 ipmi_control_get_val_cb get_val; 198 ipmi_control_set_display_string_cb set_display_string; 199 ipmi_control_get_display_string_cb get_display_string; 200 ipmi_control_identifier_get_val_cb get_identifier_val; 201 ipmi_control_identifier_set_val_cb set_identifier_val; 202 ipmi_control_set_light_cb set_light; 203 ipmi_control_get_light_cb get_light; 204 } ipmi_control_cbs_t; 205 206 /* For settings-based LEDs. */ 207 int ipmi_control_add_light_color_support(ipmi_control_t *control, 208 int light_num, 209 unsigned int color); 210 int ipmi_control_light_set_has_local_control(ipmi_control_t *control, 211 int light_num, 212 int val); 213 214 void ipmi_control_identifier_set_max_length(ipmi_control_t *control, 215 unsigned int val); 216 217 void ipmi_control_set_id(ipmi_control_t *control, char *id, 218 enum ipmi_str_type_e type, int length); 219 void ipmi_control_set_type(ipmi_control_t *control, int val); 220 void ipmi_control_set_settable(ipmi_control_t *control, int val); 221 void ipmi_control_set_readable(ipmi_control_t *control, int val); 222 void ipmi_control_set_ignore_if_no_entity(ipmi_control_t *control, 223 int ignore_if_no_entity); 224 ipmi_domain_t *ipmi_control_get_domain(ipmi_control_t *control); 225 226 /* Returns true if this control is a hot-swap indicator, meaning that 227 is is used to indicate to the operator when it is save to remove a 228 hot-swappable device. Setting "val" to one enables the control as 229 a hot-swap power control. The 'val" setting is retured by the get 230 function. The active_val is the value to use to turn off the 231 indicator (in active state). The req_act_val is the value to set 232 when requesting deactivation. The req_deact_val is the value to set 233 when requesting deactivation. The inactive val is the value to use 234 when inactive. */ 235 int ipmi_control_is_hot_swap_indicator(ipmi_control_t *control, 236 int *req_act_val, 237 int *active_val, 238 int *req_deact_val, 239 int *inactive_val); 240 void ipmi_control_set_hot_swap_indicator(ipmi_control_t *control, 241 int val, 242 int req_act_val, 243 int active_val, 244 int req_deact_val, 245 int inactive_val); 246 247 /* Get/set the control as a hot-swap power control. This must be set 248 to 1 to turn the power on and zero to turn it off. */ 249 int ipmi_control_is_hot_swap_power(ipmi_control_t *control); 250 void ipmi_control_set_hot_swap_power(ipmi_control_t *control, int val); 251 252 /* Can this control generate events? */ 253 void ipmi_control_set_has_events(ipmi_control_t *control, int val); 254 255 /* Allow OEM code to call the event handlers. Note that if the event 256 is handled by the handlers, then "*event" will be set to NULL and 257 *handled will be set to true. If the event is not handled, then 258 *handled will be set to false and the event value will be 259 unchanged. This is to help the OEM handlers only deliver the event 260 once to the user. */ 261 void ipmi_control_call_val_event_handlers(ipmi_control_t *control, 262 int *valid_vals, 263 int *vals, 264 ipmi_event_t **event, 265 int *handled); 266 267 typedef struct ipmi_control_transition_s 268 { 269 unsigned int color; 270 unsigned int time; 271 } ipmi_control_transition_t; 272 typedef struct ipmi_control_value_s 273 { 274 unsigned int num_transitions; 275 ipmi_control_transition_t *transitions; 276 } ipmi_control_value_t; 277 typedef struct ipmi_control_light_s 278 { 279 unsigned int num_values; 280 ipmi_control_value_t *values; 281 } ipmi_control_light_t; 282 void ipmi_control_light_set_lights(ipmi_control_t *control, 283 unsigned int num_lights, 284 ipmi_control_light_t *lights); 285 286 void ipmi_control_set_num_elements(ipmi_control_t *control, unsigned int val); 287 288 int ipmi_control_get_num(ipmi_control_t *control, 289 int *lun, 290 int *num); 291 292 typedef void (*ipmi_control_cleanup_oem_info_cb)(ipmi_control_t *control, 293 void *oem_info); 294 void ipmi_control_set_oem_info(ipmi_control_t *control, void *oem_info, 295 ipmi_control_cleanup_oem_info_cb cleanup_handler); 296 void *ipmi_control_get_oem_info(ipmi_control_t *control); 297 298 /* Can be used by OEM code to replace some or all of the callbacks for 299 a control. */ 300 void ipmi_control_get_callbacks(ipmi_control_t *control, 301 ipmi_control_cbs_t *cbs); 302 void ipmi_control_set_callbacks(ipmi_control_t *control, 303 ipmi_control_cbs_t *cbs); 304 305 /* Get the MC that the control is in. */ 306 ipmi_mc_t *ipmi_control_get_mc(ipmi_control_t *control); 307 308 /* OpenIPMI defines controls f0-ff for its own use, don't use them for your 309 controls. Here's some controls it defines. */ 310 #define IPMI_CHASSIS_POWER_CONTROL 0xf0 311 #define IPMI_CHASSIS_RESET_CONTROL 0xf1 312 313 /* Do a pointer callback but ignore the sequence number in the MC. 314 This is primarily for handling incoming events, where the sequence 315 number doesn't matter. */ 316 int ipmi_control_pointer_noseq_cb(ipmi_control_id_t id, 317 ipmi_control_ptr_cb handler, 318 void *cb_data); 319 320 #endif /* OPENIPMI_CONTROL_H */ 321