1 /* 2 * ipmi_domain.h 3 * 4 * MontaVista IPMI interface for management domains 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_DOMAIN_H 35 #define OPENIPMI_DOMAIN_H 36 #include <OpenIPMI/ipmi_types.h> 37 #include <OpenIPMI/os_handler.h> 38 #include <OpenIPMI/ipmi_sdr.h> 39 #include <OpenIPMI/ipmi_addr.h> 40 #include <OpenIPMI/ipmi_fru.h> 41 42 #include <OpenIPMI/internal/ipmi_entity.h> 43 #include <OpenIPMI/internal/ipmi_sensor.h> 44 #include <OpenIPMI/internal/ipmi_control.h> 45 46 /* Handle validation and usecounts on domains. */ 47 int i_ipmi_domain_get(ipmi_domain_t *domain); 48 void i_ipmi_domain_put(ipmi_domain_t *domain); 49 50 /* Return the OS handler used by the mc. */ 51 os_handler_t *ipmi_domain_get_os_hnd(ipmi_domain_t *domain); 52 53 /* Return the entity info for the given domain. */ 54 ipmi_entity_info_t *ipmi_domain_get_entities(ipmi_domain_t *domain); 55 56 /* Should the BMC do a full bus scan at startup? This is so OEM 57 code can turn this function off. The value is a boolean. */ 58 int ipmi_domain_set_full_bus_scan(ipmi_domain_t *domain, int val); 59 60 int ipmi_domain_get_event_rcvr(ipmi_domain_t *domain); 61 62 /* Allocate an MC in the domain. It doesn't add it to the domain's 63 list, to allow the MC to be setup before that happens. */ 64 int ipmi_create_mc(ipmi_domain_t *domain, 65 const ipmi_addr_t *addr, 66 unsigned int addr_len, 67 ipmi_mc_t **new_mc); 68 69 int i_ipmi_remove_mc_from_domain(ipmi_domain_t *domain, ipmi_mc_t *mc); 70 71 /* Attempt to find the MC, and if it doesn't exist create it and 72 return it. */ 73 int i_ipmi_find_or_create_mc_by_slave_addr(ipmi_domain_t *domain, 74 unsigned int channel, 75 unsigned int slave_addr, 76 ipmi_mc_t **mc); 77 78 /* Find the MC with the given IPMI address, or return NULL if not 79 found. */ 80 ipmi_mc_t *i_ipmi_find_mc_by_addr(ipmi_domain_t *domain, 81 const ipmi_addr_t *addr, 82 unsigned int addr_len); 83 84 /* Return the SDRs for the given MC, or the main set of SDRs if the MC 85 is NULL. */ 86 void i_ipmi_get_sdr_sensors(ipmi_domain_t *domain, 87 ipmi_mc_t *mc, 88 ipmi_sensor_t ***sensors, 89 unsigned int *count); 90 91 /* Set the SDRs for the given MC, or the main set of SDRs if the MC is 92 NULL. */ 93 void i_ipmi_set_sdr_sensors(ipmi_domain_t *domain, 94 ipmi_mc_t *mc, 95 ipmi_sensor_t **sensors, 96 unsigned int count); 97 98 /* Returns/set the SDRs entity info for the given MC, or the main set 99 of SDRs if the MC is NULL. */ 100 void *i_ipmi_get_sdr_entities(ipmi_domain_t *domain, 101 ipmi_mc_t *mc); 102 void i_ipmi_set_sdr_entities(ipmi_domain_t *domain, 103 ipmi_mc_t *mc, 104 void *entities); 105 106 /* Add an MC to the list of MCs in the domain. */ 107 int ipmi_add_mc_to_domain(ipmi_domain_t *domain, ipmi_mc_t *mc); 108 109 /* Remove an MC from the list of MCs in the domain. */ 110 int ipmi_remove_mc_from_domain(ipmi_domain_t *domain, ipmi_mc_t *mc); 111 112 /* The old interfaces (for backwards compatability). DON'T USE THESE!! */ 113 struct ipmi_domain_mc_upd_s; 114 typedef struct ipmi_domain_mc_upd_s ipmi_domain_mc_upd_t 115 IPMI_TYPE_DEPRECATED; 116 int ipmi_domain_register_mc_update_handler(ipmi_domain_t *domain, 117 ipmi_domain_mc_upd_cb handler, 118 void *cb_data, 119 struct ipmi_domain_mc_upd_s **id) 120 IPMI_FUNC_DEPRECATED; 121 void ipmi_domain_remove_mc_update_handler(ipmi_domain_t *domain, 122 struct ipmi_domain_mc_upd_s *id) 123 IPMI_FUNC_DEPRECATED; 124 125 /* Call any OEM handlers for the given MC. */ 126 int i_ipmi_domain_check_oem_handlers(ipmi_domain_t *domain, ipmi_mc_t *mc); 127 128 /* Scan a system interface address for an MC. */ 129 int ipmi_start_si_scan(ipmi_domain_t *domain, 130 int si_num, 131 ipmi_domain_cb done_handler, 132 void *cb_data); 133 134 /* Add an IPMB address to a list of addresses to not scan. This way, 135 if you have weak puny devices in IPMB that will break if you do 136 normal IPMB operations, you can have them be ignored. */ 137 int ipmi_domain_add_ipmb_ignore(ipmi_domain_t *domain, 138 unsigned char channel, 139 unsigned char ipmb_addr); 140 int ipmi_domain_add_ipmb_ignore_range(ipmi_domain_t *domain, 141 unsigned char channel, 142 unsigned char first_ipmb_addr, 143 unsigned char last_ipmb_addr); 144 145 /* If OEM code gets and event and it doesn't deliver it to the user, 146 it should deliver it this way, that way it can be delivered to the 147 user to be deleted. */ 148 void ipmi_handle_unhandled_event(ipmi_domain_t *domain, ipmi_event_t *event); 149 150 /* Handle a new event from something, usually from an SEL. */ 151 void i_ipmi_domain_system_event_handler(ipmi_domain_t *domain, 152 ipmi_mc_t *mc, 153 ipmi_event_t *event); 154 155 /* Returns the main SDR repository for the domain, or NULL if there is 156 not one. */ 157 ipmi_sdr_info_t *ipmi_domain_get_main_sdrs(ipmi_domain_t *domain); 158 159 /* Get the number of channels the domain supports. */ 160 int ipmi_domain_get_num_channels(ipmi_domain_t *domain, int *val); 161 162 /* Get information about a channel by index. The index is not 163 necessarily the channel number, just an array index (up to the 164 number of channels). Get the channel number from the returned 165 information. */ 166 int ipmi_domain_get_channel(ipmi_domain_t *domain, 167 int index, 168 ipmi_chan_info_t *chan); 169 170 /* These calls deal with OEM-type handlers for domains. Certain 171 domains can be detected with special means (beyond just the 172 manufacturer and product id) and this allows handlers for these 173 types of domains to be registered. At the very initial connection 174 of every domain, the handler will be called and it must detect 175 whether this is the specific type of domain or not, do any setup 176 for that domain type, and then call the done routine passed in. 177 Note that the done routine may be called later, (allowing this 178 handler to send messages and the like) but it *must* be called. 179 Note that the error value in the check_done routine should be 180 ENOSYS if the specific OEM handlers were not applicable, 0 if the 181 OEM handlers were installed, and anything else for specific 182 errors installing the OEM handlers. */ 183 typedef void (*ipmi_domain_oem_check_done)(ipmi_domain_t *domain, 184 int err, 185 void *cb_data); 186 typedef int (*ipmi_domain_oem_check)(ipmi_domain_t *domain, 187 ipmi_domain_oem_check_done done, 188 void *cb_data); 189 int ipmi_register_domain_oem_check(ipmi_domain_oem_check check, 190 void *cb_data); 191 int ipmi_deregister_domain_oem_check(ipmi_domain_oem_check check, 192 void *cb_data); 193 194 /* Register OEM data for the domain. Note that you can set a function 195 that will be called after all the domain messages have been flushed 196 but before anything else is destroyed. If the OEM data or 197 destroyer is NULL, it will not be called. */ 198 typedef void (*ipmi_domain_destroy_oem_data_cb)(ipmi_domain_t *domain, 199 void *oem_data); 200 void ipmi_domain_set_oem_data(ipmi_domain_t *domain, 201 void *oem_data, 202 ipmi_domain_destroy_oem_data_cb destroyer); 203 void *ipmi_domain_get_oem_data(ipmi_domain_t *domain); 204 205 /* Register a call that will be done at the beginning of the domain 206 shutdown process. Setting it to NULL will disable it. */ 207 typedef void (*ipmi_domain_shutdown_cb)(ipmi_domain_t *domain); 208 void ipmi_domain_set_oem_shutdown_handler(ipmi_domain_t *domain, 209 ipmi_domain_shutdown_cb handler); 210 211 /* Used to implement special handling of FRU data for locking, 212 timestamps, etc. */ 213 typedef int (*i_ipmi_domain_fru_setup_cb)(ipmi_domain_t *domain, 214 unsigned char is_logical, 215 unsigned char device_address, 216 unsigned char device_id, 217 unsigned char lun, 218 unsigned char private_bus, 219 unsigned char channel, 220 ipmi_fru_t *fru, 221 void *cb_data); 222 int i_ipmi_domain_fru_set_special_setup(ipmi_domain_t *domain, 223 i_ipmi_domain_fru_setup_cb setup, 224 void *cb_data); 225 int i_ipmi_domain_fru_call_special_setup(ipmi_domain_t *domain, 226 unsigned char is_logical, 227 unsigned char device_address, 228 unsigned char device_id, 229 unsigned char lun, 230 unsigned char private_bus, 231 unsigned char channel, 232 ipmi_fru_t *fru); 233 234 /* Set the domain type for a domain. */ 235 void ipmi_domain_set_type(ipmi_domain_t *domain, enum ipmi_domain_type dtype); 236 237 /* OEM code can call this to do its own bus scanning to speed things 238 up. Must be holding the domain MC lock (i_ipmi_domain_mc_lock()) to 239 call this. */ 240 void i_ipmi_start_mc_scan_one(ipmi_domain_t *domain, int chan, 241 int first, int last); 242 243 /* Can be used to generate unique numbers for a domain. */ 244 unsigned int ipmi_domain_get_unique_num(ipmi_domain_t *domain); 245 246 /* Initialize the domain code, called only once at init time. */ 247 int i_ipmi_domain_init(void); 248 249 /* Clean up the global domain memory. */ 250 void i_ipmi_domain_shutdown(void); 251 252 /* Is the domain currently in shutdown? */ 253 int i_ipmi_domain_in_shutdown(ipmi_domain_t *domain); 254 255 /* Used as a refcount to know when the domain is completely 256 operational. */ 257 void i_ipmi_get_domain_fully_up(ipmi_domain_t *domain, const char *name); 258 void i_ipmi_put_domain_fully_up(ipmi_domain_t *domain, const char *name); 259 260 /* Return connections for a domain. */ 261 int i_ipmi_domain_get_connection(ipmi_domain_t *domain, 262 int con_num, 263 ipmi_con_t **con); 264 265 /* Option settings. */ 266 int ipmi_option_SDRs(ipmi_domain_t *domain); 267 int ipmi_option_SEL(ipmi_domain_t *domain); 268 int ipmi_option_FRUs(ipmi_domain_t *domain); 269 int ipmi_option_IPMB_scan(ipmi_domain_t *domain); 270 int ipmi_option_OEM_init(ipmi_domain_t *domain); 271 int ipmi_option_set_event_rcvr(ipmi_domain_t *domain); 272 int ipmi_option_set_sel_time(ipmi_domain_t *domain); 273 int ipmi_option_activate_if_possible(ipmi_domain_t *domain); 274 int ipmi_option_local_only(ipmi_domain_t *domain); 275 int ipmi_option_use_cache(ipmi_domain_t *domain); 276 277 void i_ipmi_option_set_local_only_if_not_specified(ipmi_domain_t *domain, 278 int val); 279 280 /* 281 * Domain attribute handling. 282 * 283 * An attribute is a string name that is registered with the domain along 284 * with a void data item. This allows things to be attached to the domain 285 * but not directly coupled to the domain. Names that begin with "ipmi_" 286 * belong to OpenIPMI, DON'T USE THEM. OEM names should start with 287 * "oem_<type>_". Other names are free for use by the application. 288 * 289 * Note that attributes are ummutable after creation and cannot be 290 * destroyed. Destruction only happens when the domain goes away, but 291 * may be delayed to after the domain is gone due to race conditions. 292 */ 293 294 /* Attr init function. Return the data item in the data field. Returns 295 an error value. */ 296 typedef int (*ipmi_domain_attr_init_cb)(ipmi_domain_t *domain, void *cb_data, 297 void **data); 298 299 /* Called when the attribute is destroyed. Note that this may happen 300 after domain destruction, so the domain may not exist any more. */ 301 typedef void (*ipmi_domain_attr_kill_cb)(void *cb_data, void *data); 302 303 typedef struct ipmi_domain_attr_s ipmi_domain_attr_t; 304 305 /* Find an attribute for a domain. If the attribute is not found, 306 register the attribute. If the registration occurs, the init() 307 function will be called (if non-null); it must return the data item 308 in the data field. When the domain is destroyed, the destroy 309 function will be called (if not null). */ 310 int ipmi_domain_register_attribute(ipmi_domain_t *domain, 311 char *name, 312 ipmi_domain_attr_init_cb init, 313 ipmi_domain_attr_kill_cb destroy, 314 void *cb_data, 315 ipmi_domain_attr_t **attr); 316 317 /* Find an attribute in an domain. Returns EINVAL if the name is not 318 registered. Returns 0 on success, and the data item is 319 returned. */ 320 int ipmi_domain_find_attribute(ipmi_domain_t *domain, 321 char *name, 322 ipmi_domain_attr_t **attr); 323 324 /* Like the previous call, but takes a domain id. */ 325 int ipmi_domain_id_find_attribute(ipmi_domain_id_t domain_id, 326 char *name, 327 ipmi_domain_attr_t **data); 328 329 /* Get the data item from the attr. */ 330 void *ipmi_domain_attr_get_data(ipmi_domain_attr_t *attr); 331 332 /* Call this when you are done with the attr. */ 333 void ipmi_domain_attr_put(ipmi_domain_attr_t *attr); 334 335 /* Add/Remove a function, that is called when any new sensor is 336 added to the system and it allows OEM code to update information 337 about it if there are domain-specific sensor types that need 338 to be adjusted. 339 */ 340 typedef void (*ipmi_domain_sensor_cb)(ipmi_domain_t *domain, 341 ipmi_sensor_t *sensor, 342 void *cb_data); 343 344 int 345 ipmi_domain_add_new_sensor_handler(ipmi_domain_t *domain, 346 ipmi_domain_sensor_cb handler, 347 void *cb_data); 348 349 int 350 ipmi_domain_remove_new_sensor_handler(ipmi_domain_t *domain, 351 ipmi_domain_sensor_cb handler, 352 void *cb_data); 353 354 int 355 i_call_new_sensor_handlers(ipmi_domain_t *domain, 356 ipmi_sensor_t *sensor); 357 358 359 #endif /* OPENIPMI_DOMAIN_H */ 360