📄 ipmiif.h
字号:
/* * ipmiif.h * * MontaVista IPMI main interface * * Author: MontaVista Software, Inc. * Corey Minyard <minyard@mvista.com> * source@mvista.com * * Copyright 2002,2003 MontaVista Software Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#ifndef __IPMIIF_H#define __IPMIIF_H/* For version detection */#define OPENIPMI_VERSION_MAJOR 1#define OPENIPMI_VERSION_MINOR 3#define OPENIPMI_VERSION_RELEASE 9#define OPENIPMI_VERSION_EXTRA #define OPENIPMI_STRINGX(x) #x#define OPENIPMI_XSTRING(x) OPENIPMI_STRINGX(x)#define OPENIPMI_VERSION OPENIPMI_XSTRING(OPENIPMI_VERSION_MAJOR) \ "." OPENIPMI_XSTRING(OPENIPMI_VERSION_MINOR) \ "." OPENIPMI_XSTRING(OPENIPMI_VERSION_RELEASE) \ OPENIPMI_XSTRING(OPENIPMI_VERSION_EXTRA)/* * This is the main include file for dealing with IPMI. It provides * an abstract interface to the IPMI system, so you don't have to deal * with all the nitty-gritty details of IPMI. You only deal with * four things: * * Domain - This is the main interface to the IPMI system. * Entities - These are things that sensors monitor, they can be * FRUs, or whatnot. * Sensors - These are monitors for FRUs. * Controls - These are output devices * * You don't have to deal with Management Controllers (MCs), IPMI * addressing, or anything like that. This software will go out onto * the IPMB bus, detect all the MCs and entities present there, and * call you when it detects something. It reads the SDR database and * detects all the entities and entity relationships. It lets you add * entities and relationships to the local copies, and write the * information back into the database. * * You have to be careful with locking in this system. The four things * you deal with all have two ways to get at them: An ID, and a pointer. * The ID is always valid, you can store that off on your own and use it * later. The pointer is only valid inside a callback, the system is * free to change the pointers for a thing when no callbacks are active. * * To convert an ID to a pointer that you can work on, you have to go * through a callback. These are provided for each type. This is a * little inconvenient, but it's a lot faster than copying a lot of * data around all the time or re-validating an ID on every operation. * If a callback gives you a pointer to a sensor, entity, or domain, the * lock for that things will be held while you are in the callback. * * This interface is completely event-driven, meaning that a call will * never block. Instead, if a call cannot complete inside the call * itself, you provide a "callback" that will be called when the * operation completes. If you don't care about the results, you can * provide a NULL callback. However, you will not receive any error * information about the operation; if it fails you will not know. * Note that if a function that you provide a callback returns an * error, the callback will NEVER be called. * * Callbacks are possible on things that have ceased to exist. For * example, if you start an operation on a sensor and the sensor * ceases to exist during the operation, you will get an error * callback with a NULL sensor. The same goes for controls, entities, * or anything else. * * You should NEVER block or exit in a callback. Locks are held in * callbacks, so you will constipate the system if you block in * callbacks. Just don't do it. */#include <time.h>#include <OpenIPMI/ipmi_types.h>#include <OpenIPMI/ipmi_bits.h>#include <OpenIPMI/os_handler.h>/* This is how you convert a pointer to and ID and convert an ID to a pointer. Pointers are ONLY valid in callbacks, the system is free to change the pointer value outside the callback. So you should only store IDs. IDs are good all the time, but you must go through the "pointer_cb" functions to get a usable pointer you can operate on. This is how the locking works for this, inside the callback you will hold the locks so the item you are using will not change. It's kind of a pain, but it improves reliability. This way, you cannot "forget" to release the lock for something. Note that this callback function you provide will be called immediately in the same thread of execution, this callback is not delayed or spawned off to another thread. *//* The comparisons below return -1 if id1<id2, 0 if id1==id2, and 1 if id1>id2. *//* This ipmi_xxx_id_set_invalid() functions set the passed in domain id to an invalid value that is always the same and guaranteed to be invalid. */ipmi_domain_id_t ipmi_domain_convert_to_id(ipmi_domain_t *domain);typedef void (*ipmi_domain_ptr_cb)(ipmi_domain_t *domain, void *cb_data);int ipmi_domain_pointer_cb(ipmi_domain_id_t id, ipmi_domain_ptr_cb handler, void *cb_data);int ipmi_cmp_domain_id(ipmi_domain_id_t id1, ipmi_domain_id_t id2);void ipmi_domain_id_set_invalid(ipmi_domain_id_t *id);int ipmi_domain_id_is_invalid(ipmi_domain_id_t *id);ipmi_entity_id_t ipmi_entity_convert_to_id(ipmi_entity_t *ent);typedef void (*ipmi_entity_ptr_cb)(ipmi_entity_t *entity, void *cb_data);int ipmi_entity_pointer_cb(ipmi_entity_id_t id, ipmi_entity_ptr_cb handler, void *cb_data);int ipmi_entity_find_id(ipmi_domain_id_t domain_id, int entity_id, int entity_instance, int channel, int slave_address, ipmi_entity_id_t *id);void ipmi_entity_id_set_invalid(ipmi_entity_id_t *id);int ipmi_entity_id_is_invalid(ipmi_entity_id_t *id);ipmi_sensor_id_t ipmi_sensor_convert_to_id(ipmi_sensor_t *sensor);typedef void (*ipmi_sensor_ptr_cb)(ipmi_sensor_t *sensor, void *cb_data);int ipmi_sensor_pointer_cb(ipmi_sensor_id_t id, ipmi_sensor_ptr_cb handler, void *cb_data);int ipmi_cmp_sensor_id(ipmi_sensor_id_t id1, ipmi_sensor_id_t id2);int ipmi_sensor_find_id(ipmi_domain_id_t domain_id, int entity_id, int entity_instance, int channel, int slave_address, char *id_name, ipmi_sensor_id_t *id);void ipmi_sensor_id_set_invalid(ipmi_sensor_id_t *id);int ipmi_sensor_id_is_invalid(ipmi_sensor_id_t *id);ipmi_control_id_t ipmi_control_convert_to_id(ipmi_control_t *control);typedef void (*ipmi_control_ptr_cb)(ipmi_control_t *control, void *cb_data);int ipmi_control_pointer_cb(ipmi_control_id_t id, ipmi_control_ptr_cb handler, void *cb_data);int ipmi_cmp_control_id(ipmi_control_id_t id1, ipmi_control_id_t id2);int ipmi_control_find_id(ipmi_domain_id_t domain_id, int entity_id, int entity_instance, int channel, int slave_address, char *id_name, ipmi_control_id_t *id);void ipmi_control_id_set_invalid(ipmi_control_id_t *id);int ipmi_control_id_is_invalid(ipmi_control_id_t *id);/* Callback used for generic domain reporting. */typedef void (*ipmi_domain_cb)(ipmi_domain_t *domain, int err, void *cb_data);typedef struct ipmi_domain_con_change_s ipmi_domain_con_change_t;/* Set and get a "name" for the domain. This name is used for logging errors, so errors from domains can be separated. You should set one if you support multiple domains. The max length is the number of characters, not including the nil at the end. A longer name will be silently truncated when set. When getting the name, the actual length of the "name" array must be the max length + 1 to be able to be sure to get the full name. The actual length of the name array must be put into "len" before calling (the actual length must including the terminating nil), the actual length, including the terminating nil, is put into "len". This setting should be done very early (before or at the point when the connection comes up), as other things will pull the name and use it. */#define IPMI_MAX_DOMAIN_NAME_LEN 32void ipmi_domain_set_name(ipmi_domain_t *domain, char *name);void ipmi_domain_get_name(ipmi_domain_t *domain, char *name, int *len);/* Add and remove a function to be called when the connection or port to the domain goes down or back up. Being down does NOT mean the domain has been shutdown, it is still active, and OpenIPMI will continue to attempt to reconnect to the domain. When the connection goes down, The "err" value in the callback will be non-zero to report the reason for the failure. When the connection goes up, the "err" value will be zero reporting that the connection is now available. The particular connections that went up or down is reported. conn_num is the connection number (which ipmi_con_t supplied in the array at startup), port_num is the particular port on the connection, and depends on the connection type. still_connected is true if the system still has a valid connection to the target, or false if all connection are gone. */typedef void (*ipmi_domain_con_cb)(ipmi_domain_t *domain, int err, unsigned int conn_num, unsigned int port_num, int still_connected, void *cb_data);int ipmi_domain_add_con_change_handler(ipmi_domain_t *domain, ipmi_domain_con_cb handler, void *cb_data, ipmi_domain_con_change_t **id);void ipmi_domain_remove_con_change_handler(ipmi_domain_t *domain, ipmi_domain_con_change_t *id);/* The domain has two timers, one for the SEL rescan interval and one for the IPMB bus rescan interval. *//* The SEL rescan timer is the time between when the SEL will be checked for new events. This timer is in seconds, and will currently default to 10 seconds. You need to set this depending on how fast you need to know if events have come in. If you set this value to zero, it will turn off SEL scanning. */void ipmi_domain_set_sel_rescan_time(ipmi_domain_t *domain, unsigned int seconds);unsigned int ipmi_domain_get_sel_rescan_time(ipmi_domain_t *domain);/* The IPMB rescan timer is the time between scans of the IPMB bus to see if new MCs have appeared on the bus. The timer is in seconds, and defaults to 600 seconds (10 minutes). The setting of this timer depends on how fast you need to know if new devices have appeared, and if your system has proprietary extensions to detect insertion of devices more quickly. */void ipmi_domain_set_ipmb_rescan_time(ipmi_domain_t *domain, unsigned int seconds);unsigned int ipmi_domain_get_ipmb_rescan_time(ipmi_domain_t *domain);/* Events come in this format. */typedef void (*ipmi_event_handler_cb)(ipmi_domain_t *domain, ipmi_event_t *event, void *event_data);typedef struct ipmi_event_handler_id_s ipmi_event_handler_id_t;/* Register a handler to receive events. Multiple handlers may be registered, they will all receive all events. The event_data will be passed in with every event received. This will only catch events that are not sent to a sensor, so if you get a system software event or an event from a sensor the software doesn't know about, this handler will get it. */int ipmi_register_for_events(ipmi_domain_t *domain, ipmi_event_handler_cb handler, void *event_data, ipmi_event_handler_id_t **id);/* Deregister an event handler. */int ipmi_deregister_for_events(ipmi_domain_t *domain, ipmi_event_handler_id_t *id);/* Globally enable or disable events on the domain's interfaces. */int ipmi_domain_enable_events(ipmi_domain_t *domain);int ipmi_domain_disable_events(ipmi_domain_t *domain);/* Events in OpenIPMI are opaque structures. If an event is given to you in a callback (such as the event handler), you *cannot* keep that event, you may keep a duplicate made with ipmi_event_dup(). If you fetch an event using ipmi_domain_xxx_event(), you are given a duplicated copy. You *must* free that event, or you will leak. Note that the duplicates are currently kept with refcounts (since the events are immutable) so duplicating an event doesn't take any more memory or much CPU. *//* Copy an event. If you need to keep your own local copy of an event (to delete later, for instance) you should use this. */ipmi_event_t *ipmi_event_dup(ipmi_event_t *event);/* When you are done with an event, you should free it. This frees up the internal store for the event and removes it from the external system event event. Note that you must delete every event you duplicate. Note that this does *NOT* remove the event from the event log, you have to call ipmi_event_delete() for that. */void ipmi_event_free(ipmi_event_t *event);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -