4
* MontaVista IPMI interface, definition for a low-level connection (like a
5
* LAN interface, or system management interface, etc.).
7
* Author: MontaVista Software, Inc.
8
* Corey Minyard <minyard@mvista.com>
11
* Copyright 2002,2003 MontaVista Software Inc.
13
* This program is free software; you can redistribute it and/or
14
* modify it under the terms of the GNU Lesser General Public License
15
* as published by the Free Software Foundation; either version 2 of
16
* the License, or (at your option) any later version.
19
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
28
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
* You should have received a copy of the GNU Lesser General Public
31
* License along with this program; if not, write to the Free
32
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38
#include <OpenIPMI/ipmi_types.h>
39
#include <OpenIPMI/ipmi_addr.h>
40
#include <OpenIPMI/ipmiif.h>
41
#include <OpenIPMI/os_handler.h>
47
/* Called when an IPMI response to a command comes in from the BMC. */
48
typedef int (*ipmi_ll_rsp_handler_t)(ipmi_con_t *ipmi,
51
/* Called when an IPMI event comes in from the BMC. Note that the
52
event may be NULL, meaning that an event came in but did not have
53
enough information to build a full event message. So this is just
54
an indication that there is a new event in the event log. Note that
55
if an event is delivered here, it's mcid might be invalid, so that
56
may need to be established here. */
57
typedef void (*ipmi_ll_evt_handler_t)(ipmi_con_t *ipmi,
59
unsigned int addr_len,
63
/* Called when an incoming command is received by the IPMI code. */
64
typedef void (*ipmi_ll_cmd_handler_t)(ipmi_con_t *ipmi,
66
unsigned int addr_len,
73
/* Called when a low-level connection has failed or come up. If err
74
is zero, the connection has come up after being failed. if err is
75
non-zero, it's an error number to report why the failure occurred.
76
Since some connections support multiple ports into the system, this
77
is used to report partial failures as well as full failures.
78
port_num will be the port number that has failed (if err is
79
nonzero) or has just come up (if err is zero). What port_num that
80
means depends on the connection type. any_port_up will be true if
81
the system still has connectivity through other ports. */
82
typedef void (*ipmi_ll_con_changed_cb)(ipmi_con_t *ipmi,
84
unsigned int port_num,
88
/* Used when fetching the IPMB address of the connection. The active
89
parm tells if the interface is active or not, this callback is also
90
used to inform the upper layer when the connection becomes active
92
typedef void (*ipmi_ll_ipmb_addr_cb)(ipmi_con_t *ipmi,
94
unsigned int ipmb_addr,
99
/* Used to handle knowing when the connection shutdown is complete. */
100
typedef void (*ipmi_ll_con_closed_cb)(ipmi_con_t *ipmi, void *cb_data);
102
/* Set this bit in the hacks if, even though the connection is to a
103
device not at 0x20, the first part of a LAN command should always
105
#define IPMI_CONN_HACK_20_AS_MAIN_ADDR 0x00000001
107
/* Some systems (incorrectly, according to the spec) use only the
108
bottom 4 bits or ROLE(m) for authentication in the RAKP3 message.
109
The spec says to use all 8 bits, but enabling this hack makes
110
OpenIPMI only use the bottom 4 bits. */
111
#define IPMI_CONN_HACK_RAKP3_WRONG_ROLEM 0x00000002
113
/* The spec is vague (perhaps wrong), but the default for RMCP+ seems
114
to be to use K(1) as the integrity key. That is thus the default
115
of OpenIPMI, but this hack lets you use SIK as it says in one part
117
#define IPMI_CONN_HACK_RMCPP_INTEG_SIK 0x00000004
119
/* The data structure representing a connection. The low-level handler
120
fills this out then calls ipmi_init_con() with the connection. */
123
/* If this is zero, the domain handling code will not attempt to
124
scan the system interface address of the connection. If 1, it
125
will. Generally, if the system interface will respond on a
126
IPMB address, you should set this to zero. If it does not
127
respond on an IPMB, you should set this to one if it is a
128
management controller. */
131
/* The low-level handler should provide one of these for doing os-type
132
things (locks, random numbers, etc.) */
133
os_handler_t *os_hnd;
135
/* This data can be fetched by the user and used for anything they
139
/* Connection-specific data for the underlying connection. */
142
/* If OEM code want to attach some data, it can to it here. */
144
void (*oem_data_cleanup)(ipmi_con_t *ipmi);
146
/* This allows the connection to tell the upper layer that broadcasting
147
will not work on this interface. */
148
int broadcast_broken;
150
/* Calls for the interface. These should all return standard
151
"errno" errors if they fail. */
153
/* Start processing on a connection. Note that the handler *must*
154
be called with the global read lock not held, because the
155
handler must write lock the global lock in order to add the MC
156
to the global list. This will report success/failure with the
157
con_changed_handler, so set that up first. */
158
int (*start_con)(ipmi_con_t *ipmi);
160
/* Add a callback to call when the connection goes down or up. */
161
int (*add_con_change_handler)(ipmi_con_t *ipmi,
162
ipmi_ll_con_changed_cb handler,
164
int (*remove_con_change_handler)(ipmi_con_t *ipmi,
165
ipmi_ll_con_changed_cb handler,
168
/* If OEM code discovers that an IPMB address has changed, it can
169
use this to change it. The hacks are the same as the ones in
170
the IPMB address handler. */
171
void (*set_ipmb_addr)(ipmi_con_t *ipmi,
176
/* Add a handler that will be called when the IPMB address changes. */
177
int (*add_ipmb_addr_handler)(ipmi_con_t *ipmi,
178
ipmi_ll_ipmb_addr_cb handler,
180
int (*remove_ipmb_addr_handler)(ipmi_con_t *ipmi,
181
ipmi_ll_ipmb_addr_cb handler,
184
/* This call gets the IPMB address of the connection. It may be
185
NULL if the connection does not support this. This call may be
186
set or overridden by the OEM code. This is primarily for use
187
by the connection code itself, the OEM code for the BMC
188
connected to should set this. If it is not set, the IPMB
189
address is assumed to be 0x20. This *should* send a message to
190
the device, because connection code will assume that and use it
191
to check for device function. This should also check if the
192
device is active. If this is non-null, it will be called
194
int (*get_ipmb_addr)(ipmi_con_t *ipmi,
195
ipmi_ll_ipmb_addr_cb handler,
198
/* Change the state of the connection to be active or inactive.
199
This may be NULL if the connection does not support this. The
200
interface code may set this, the OEM code should override this
202
int (*set_active_state)(ipmi_con_t *ipmi,
204
ipmi_ll_ipmb_addr_cb handler,
207
/* Send an IPMI command (in "msg" on the "ipmi" connection to the
208
given "addr". When the response comes in or the message times
209
out, rsp_handler will be called with the following four data
210
items. Note that the lower layer MUST guarantee that the
211
reponse handler is called, even if it fails or the message is
213
int (*send_command)(ipmi_con_t *ipmi,
215
unsigned int addr_len,
217
ipmi_ll_rsp_handler_t rsp_handler,
220
/* Register to receive IPMI events from the interface. */
221
int (*add_event_handler)(ipmi_con_t *ipmi,
222
ipmi_ll_evt_handler_t handler,
225
/* Remove an event handler. */
226
int (*remove_event_handler)(ipmi_con_t *ipmi,
227
ipmi_ll_evt_handler_t handler,
230
/* Send a response message. This is not supported on all
231
interfaces, primarily only on system management interfaces. If
232
not supported, this should return ENOSYS. */
233
int (*send_response)(ipmi_con_t *ipmi,
235
unsigned int addr_len,
239
/* Register to receive incoming commands. This is not supported
240
on all interfaces, primarily only on system management
241
interfaces. If not supported, this should return ENOSYS. */
242
int (*register_for_command)(ipmi_con_t *ipmi,
245
ipmi_ll_cmd_handler_t handler,
250
/* Deregister a command registration. This is not supported on
251
all interfaces, primarily only on system management interfaces.
252
If not supported, this should return ENOSYS. */
253
int (*deregister_for_command)(ipmi_con_t *ipmi,
257
/* Close an IPMI connection. */
258
int (*close_connection)(ipmi_con_t *ipmi);
260
/* This is set by OEM code to handle certain conditions when a
261
send message fails. It is currently only used by the IPMI LAN
262
code, if a send messages response is an error, this will be
263
called first. If this function returns true, then the IPMI LAN
264
code will not do anything with the message. */
265
int (*handle_send_rsp_err)(ipmi_con_t *con, ipmi_msg_t *msg);
267
/* Name the connection code can use for logging and instance names
268
for statistics. Must be dynamically allocated with
269
ipmi_mem_alloc(). The connection code will free this. May be
273
/* The connection code may put a string here to identify
277
/* The privilege level of the connection */
278
unsigned int priv_level;
280
/* Close an IPMI connection and report that it is closed. */
281
int (*close_connection_done)(ipmi_con_t *ipmi,
282
ipmi_ll_con_closed_cb handler,
285
/* Hacks reported by OEM code. This should be set by the lower
286
layer or by the user interface code. */
289
/* The IPMB address as reported by the lower layer. */
290
unsigned char ipmb_addr;
292
/* Handle an async event for the connection reported by something
294
void (*handle_async_event)(ipmi_con_t *con,
296
unsigned int addr_len,
299
/* Used by the connection attribute code. Don't do anything with
300
this yourself!. The thing that creates this connection should
301
call ipmi_con_attr_init() when the connection is created and
302
ipmi_con_attr_cleanup() when the connection is destroyed. */
305
/* Statistics interfaces. These may be NULL if the user doesn't
306
want statistics. They pass in the user data field. */
307
int (*register_stat)(void *user_data, char *name,
308
char *instance, void **stat);
309
void (*add_stat)(void *user_data, void *stat, int value);
310
void (*finished_with_stat)(void *user_data, void *stat);
313
#define IPMI_CONN_NAME(c) (c->name ? c->name : "")
315
/* Initialization code for the initialization the connection code. */
316
int _ipmi_conn_init(os_handler_t *os_hnd);
317
void _ipmi_conn_shutdown(void);
320
/* Address types for external addresses. */
321
#define IPMI_EXTERN_ADDR_IP 1
323
/* Handle a trap from an external SNMP source. It returns 1 if the
324
event was handled an zero if it was not. */
325
int ipmi_handle_snmp_trap_data(void *src_addr,
326
unsigned int src_addr_len,
330
unsigned int data_len);
332
/* These calls deal with OEM-type handlers for connections. Certain
333
connections can be detected with special means (beyond just the
334
manufacturer and product id) and this allows handlers for these
335
types of connections to be registered. At the very initial
336
connection of every connection, the handler will be called and it
337
must detect whether this is the specific type of connection or not,
338
do any setup for that connection type, and then call the done
339
routine passed in. Note that the done routine may be called later,
340
(allowing this handler to send messages and the like) but it *must*
341
be called. Note that this has no cancellation handler. It relies
342
on the lower levels returning responses for all the commands with
344
typedef void (*ipmi_conn_oem_check_done)(ipmi_con_t *conn,
346
typedef int (*ipmi_conn_oem_check)(ipmi_con_t *conn,
348
ipmi_conn_oem_check_done done,
350
int ipmi_register_conn_oem_check(ipmi_conn_oem_check check,
352
int ipmi_deregister_conn_oem_check(ipmi_conn_oem_check check,
354
/* Should be called by the connection code for any new connection. */
355
int ipmi_conn_check_oem_handlers(ipmi_con_t *conn,
356
ipmi_conn_oem_check_done done,
359
/* Generic message handling */
360
void ipmi_handle_rsp_item(ipmi_con_t *ipmi,
362
ipmi_ll_rsp_handler_t rsp_handler);
364
void ipmi_handle_rsp_item_copymsg(ipmi_con_t *ipmi,
367
ipmi_ll_rsp_handler_t rsp_handler);
369
void ipmi_handle_rsp_item_copyall(ipmi_con_t *ipmi,
372
unsigned int addr_len,
374
ipmi_ll_rsp_handler_t rsp_handler);
376
/* You should use these for allocating and freeing mesage items. Note
377
that if you set item->msg.data to a non-NULL value that is not
378
item->data, the system will free it with ipmi_free_msg_item_data().
379
So you should allocate it with ipmi_alloc_msg_item_data9). */
380
ipmi_msgi_t *ipmi_alloc_msg_item(void);
381
void ipmi_free_msg_item(ipmi_msgi_t *item);
382
void *ipmi_alloc_msg_item_data(unsigned int size);
383
void ipmi_free_msg_item_data(void *data);
384
/* Move the data from the old message item to the new one, NULL-ing
385
out the old item's data. This will free the new_item's original
386
data if necessary. This will *not* copy the data items, just the
387
address and message. */
388
void ipmi_move_msg_item(ipmi_msgi_t *new_item, ipmi_msgi_t *old_item);
391
* Connection attributes. These are named items that code may create
392
* to attach a void data item to a connection by name. It can then
393
* look up the data item by name. Note that you can call
394
* ipmi_con_register_attribute multiple times. The first time will
395
* create the item, the rest of the times will return the existing
398
* When the connection is destroyed, the destroy function will be
399
* called on the attribute so the memory (or anything else) can be
402
* This is especially for use by RMCP+ payloads so they may attach
403
* data to the connection they are associated with.
405
typedef struct ipmi_con_attr_s ipmi_con_attr_t;
407
/* Attr init function. Return the data item in the data field. Returns
408
an error value. Will only be called once for the attribute. */
409
typedef int (*ipmi_con_attr_init_cb)(ipmi_con_t *con, void *cb_data,
412
/* Called when the attribute is destroyed. Note that this may happen
413
after connection destruction, so the connection may not exist any
415
typedef void (*ipmi_con_attr_kill_cb)(void *cb_data, void *data);
417
int ipmi_con_register_attribute(ipmi_con_t *con,
419
ipmi_con_attr_init_cb init,
420
ipmi_con_attr_kill_cb destroy,
422
ipmi_con_attr_t **attr);
423
int ipmi_con_find_attribute(ipmi_con_t *con,
425
ipmi_con_attr_t **attr);
426
void *ipmi_con_attr_get_data(ipmi_con_attr_t *attr);
427
/* You must call the put operation of every attribute returned by
429
void ipmi_con_attr_put(ipmi_con_attr_t *attr);
430
int ipmi_con_attr_init(ipmi_con_t *con);
431
void ipmi_con_attr_cleanup(ipmi_con_t *con);
437
#endif /* _IPMI_CONN_H */