~ubuntu-branches/ubuntu/karmic/openipmi/karmic

« back to all changes in this revision

Viewing changes to include/OpenIPMI/ipmi_conn.h

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2005-07-04 21:29:17 UTC
  • Revision ID: james.westby@ubuntu.com-20050704212917-igddk5jawjmhrlay
Tags: upstream-2.0.1
Import upstream version 2.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ipmi_conn.h
 
3
 *
 
4
 * MontaVista IPMI interface, definition for a low-level connection (like a
 
5
 * LAN interface, or system management interface, etc.).
 
6
 *
 
7
 * Author: MontaVista Software, Inc.
 
8
 *         Corey Minyard <minyard@mvista.com>
 
9
 *         source@mvista.com
 
10
 *
 
11
 * Copyright 2002,2003 MontaVista Software Inc.
 
12
 *
 
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.
 
17
 *
 
18
 *
 
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.
 
29
 *
 
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.
 
33
 */
 
34
 
 
35
#ifndef _IPMI_CONN_H
 
36
#define _IPMI_CONN_H
 
37
 
 
38
#include <OpenIPMI/ipmi_types.h>
 
39
#include <OpenIPMI/ipmi_addr.h>
 
40
#include <OpenIPMI/ipmiif.h>
 
41
#include <OpenIPMI/os_handler.h>
 
42
 
 
43
#ifdef __cplusplus
 
44
extern "C" {
 
45
#endif
 
46
 
 
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,
 
49
                                     ipmi_msgi_t  *rspi);
 
50
 
 
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,
 
58
                                      ipmi_addr_t  *addr,
 
59
                                      unsigned int addr_len,
 
60
                                      ipmi_event_t *event,
 
61
                                      void         *cb_data);
 
62
 
 
63
/* Called when an incoming command is received by the IPMI code. */
 
64
typedef void (*ipmi_ll_cmd_handler_t)(ipmi_con_t   *ipmi,
 
65
                                      ipmi_addr_t  *addr,
 
66
                                      unsigned int addr_len,
 
67
                                      ipmi_msg_t   *cmd,
 
68
                                      long         sequence,
 
69
                                      void         *cmd_data,
 
70
                                      void         *data2,
 
71
                                      void         *data3);
 
72
 
 
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,
 
83
                                       int          err,
 
84
                                       unsigned int port_num,
 
85
                                       int          any_port_up,
 
86
                                       void         *cb_data);
 
87
 
 
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
 
91
   or inactive. */
 
92
typedef void (*ipmi_ll_ipmb_addr_cb)(ipmi_con_t   *ipmi,
 
93
                                     int          err,
 
94
                                     unsigned int ipmb_addr,
 
95
                                     int          active,
 
96
                                     unsigned int hacks,
 
97
                                     void         *cb_data);
 
98
 
 
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);
 
101
 
 
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
 
104
   use 0x20. */
 
105
#define IPMI_CONN_HACK_20_AS_MAIN_ADDR          0x00000001
 
106
 
 
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
 
112
 
 
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
 
116
   of the spec. */
 
117
#define IPMI_CONN_HACK_RMCPP_INTEG_SIK          0x00000004
 
118
 
 
119
/* The data structure representing a connection.  The low-level handler
 
120
   fills this out then calls ipmi_init_con() with the connection. */
 
121
struct ipmi_con_s
 
122
{
 
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. */
 
129
    int scan_sysaddr;
 
130
 
 
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;
 
134
 
 
135
    /* This data can be fetched by the user and used for anything they
 
136
       like. */
 
137
    void *user_data;
 
138
 
 
139
    /* Connection-specific data for the underlying connection. */
 
140
    void *con_data;
 
141
 
 
142
    /* If OEM code want to attach some data, it can to it here. */
 
143
    void *oem_data;
 
144
    void (*oem_data_cleanup)(ipmi_con_t *ipmi);
 
145
 
 
146
    /* This allows the connection to tell the upper layer that broadcasting
 
147
       will not work on this interface. */
 
148
    int broadcast_broken;
 
149
 
 
150
    /* Calls for the interface.  These should all return standard
 
151
       "errno" errors if they fail. */
 
152
 
 
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);
 
159
 
 
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,
 
163
                                  void                   *cb_data);
 
164
    int (*remove_con_change_handler)(ipmi_con_t             *ipmi,
 
165
                                     ipmi_ll_con_changed_cb handler,
 
166
                                     void                   *cb_data);
 
167
 
 
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,
 
172
                          unsigned char ipmb,
 
173
                          int           active,
 
174
                          unsigned int  hacks);
 
175
 
 
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,
 
179
                                 void                 *cb_data);
 
180
    int (*remove_ipmb_addr_handler)(ipmi_con_t           *ipmi,
 
181
                                    ipmi_ll_ipmb_addr_cb handler,
 
182
                                    void                 *cb_data);
 
183
 
 
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
 
193
       periodically. */
 
194
    int (*get_ipmb_addr)(ipmi_con_t           *ipmi,
 
195
                         ipmi_ll_ipmb_addr_cb handler,
 
196
                         void                 *cb_data);
 
197
 
 
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
 
201
       if necessary. */
 
202
    int (*set_active_state)(ipmi_con_t           *ipmi,
 
203
                            int                  is_active,
 
204
                            ipmi_ll_ipmb_addr_cb handler,
 
205
                            void                 *cb_data);
 
206
 
 
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
 
212
       dropped. */
 
213
    int (*send_command)(ipmi_con_t            *ipmi,
 
214
                        ipmi_addr_t           *addr,
 
215
                        unsigned int          addr_len,
 
216
                        ipmi_msg_t            *msg,
 
217
                        ipmi_ll_rsp_handler_t rsp_handler,
 
218
                        ipmi_msgi_t           *rspi);
 
219
 
 
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,
 
223
                             void                       *cb_data);
 
224
 
 
225
    /* Remove an event handler. */
 
226
    int (*remove_event_handler)(ipmi_con_t                 *ipmi,
 
227
                                ipmi_ll_evt_handler_t      handler,
 
228
                                void                       *cb_data);
 
229
 
 
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,
 
234
                         ipmi_addr_t  *addr,
 
235
                         unsigned int addr_len,
 
236
                         ipmi_msg_t   *msg,
 
237
                         long         sequence);
 
238
 
 
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,
 
243
                                unsigned char         netfn,
 
244
                                unsigned char         cmd,
 
245
                                ipmi_ll_cmd_handler_t handler,
 
246
                                void                  *cmd_data,
 
247
                                void                  *data2,
 
248
                                void                  *data3);
 
249
 
 
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,
 
254
                                  unsigned char netfn,
 
255
                                  unsigned char cmd);
 
256
 
 
257
    /* Close an IPMI connection. */
 
258
    int (*close_connection)(ipmi_con_t *ipmi);
 
259
 
 
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);
 
266
 
 
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
 
270
       NULL. */
 
271
    char *name;
 
272
 
 
273
    /* The connection code may put a string here to identify
 
274
       itself. */
 
275
    char *con_type;
 
276
 
 
277
    /* The privilege level of the connection */
 
278
    unsigned int priv_level;
 
279
 
 
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,
 
283
                                 void                  *cb_data);
 
284
 
 
285
    /* Hacks reported by OEM code.  This should be set by the lower
 
286
       layer or by the user interface code. */
 
287
    unsigned int  hacks;
 
288
 
 
289
    /* The IPMB address as reported by the lower layer. */
 
290
    unsigned char ipmb_addr;
 
291
 
 
292
    /* Handle an async event for the connection reported by something
 
293
       else. */
 
294
    void (*handle_async_event)(ipmi_con_t   *con,
 
295
                               ipmi_addr_t  *addr,
 
296
                               unsigned int addr_len,
 
297
                               ipmi_msg_t   *msg);
 
298
 
 
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. */
 
303
    void *attr;
 
304
 
 
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);
 
311
};
 
312
 
 
313
#define IPMI_CONN_NAME(c) (c->name ? c->name : "")
 
314
 
 
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);
 
318
 
 
319
 
 
320
/* Address types for external addresses. */
 
321
#define IPMI_EXTERN_ADDR_IP     1
 
322
 
 
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,
 
327
                               int             src_addr_type,
 
328
                               long            specific,
 
329
                               unsigned char   *data,
 
330
                               unsigned int    data_len);
 
331
 
 
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
 
343
   NULL connections. */
 
344
typedef void (*ipmi_conn_oem_check_done)(ipmi_con_t *conn,
 
345
                                         void       *cb_data);
 
346
typedef int (*ipmi_conn_oem_check)(ipmi_con_t               *conn,
 
347
                                   void                     *check_cb_data,
 
348
                                   ipmi_conn_oem_check_done done,
 
349
                                   void                     *done_cb_data);
 
350
int ipmi_register_conn_oem_check(ipmi_conn_oem_check check,
 
351
                                 void                *cb_data);
 
352
int ipmi_deregister_conn_oem_check(ipmi_conn_oem_check check,
 
353
                                   void                *cb_data);
 
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,
 
357
                                 void                     *cb_data);
 
358
 
 
359
/* Generic message handling */
 
360
void ipmi_handle_rsp_item(ipmi_con_t            *ipmi,
 
361
                          ipmi_msgi_t           *rspi,
 
362
                          ipmi_ll_rsp_handler_t rsp_handler);
 
363
 
 
364
void ipmi_handle_rsp_item_copymsg(ipmi_con_t            *ipmi,
 
365
                                  ipmi_msgi_t           *rspi,
 
366
                                  ipmi_msg_t            *msg,
 
367
                                  ipmi_ll_rsp_handler_t rsp_handler);
 
368
 
 
369
void ipmi_handle_rsp_item_copyall(ipmi_con_t            *ipmi,
 
370
                                  ipmi_msgi_t           *rspi,
 
371
                                  ipmi_addr_t           *addr,
 
372
                                  unsigned int          addr_len,
 
373
                                  ipmi_msg_t            *msg,
 
374
                                  ipmi_ll_rsp_handler_t rsp_handler);
 
375
 
 
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);
 
389
 
 
390
/*
 
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
 
396
 * item.
 
397
 *
 
398
 * When the connection is destroyed, the destroy function will be
 
399
 * called on the attribute so the memory (or anything else) can be
 
400
 * cleaned up.
 
401
 *
 
402
 * This is especially for use by RMCP+ payloads so they may attach
 
403
 * data to the connection they are associated with.
 
404
 */
 
405
typedef struct ipmi_con_attr_s ipmi_con_attr_t;
 
406
 
 
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,
 
410
                                     void **data);
 
411
 
 
412
/* Called when the attribute is destroyed.  Note that this may happen
 
413
   after connection destruction, so the connection may not exist any
 
414
   more. */
 
415
typedef void (*ipmi_con_attr_kill_cb)(void *cb_data, void *data);
 
416
 
 
417
int ipmi_con_register_attribute(ipmi_con_t            *con,
 
418
                                char                  *name,
 
419
                                ipmi_con_attr_init_cb init,
 
420
                                ipmi_con_attr_kill_cb destroy,
 
421
                                void                  *cb_data,
 
422
                                ipmi_con_attr_t       **attr);
 
423
int ipmi_con_find_attribute(ipmi_con_t      *con,
 
424
                            char             *name,
 
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
 
428
   register or find. */
 
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);
 
432
 
 
433
#ifdef __cplusplus
 
434
}
 
435
#endif
 
436
 
 
437
#endif /* _IPMI_CONN_H */